linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Keith Owens <kaos@ocs.com.au>
To: "David S. Miller" <davem@redhat.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [RFC] Standard way of generating assembler offsets
Date: Sun, 14 Oct 2001 21:27:19 +1000	[thread overview]
Message-ID: <1519.1003058839@ocs3.intra.ocs.com.au> (raw)
In-Reply-To: Your message of "Mon, 08 Oct 2001 02:49:46 MST." <20011008.024946.74749362.davem@redhat.com>

On Mon, 08 Oct 2001 02:49:46 -0700 (PDT), 
"David S. Miller" <davem@redhat.com> wrote:
>BTW, I assume you have already taken a look at how we
>do this on Sparc64.  See arch/sparc64/kernel/check_asm.sh
>and the "check_asm" target in arch/sparc64/kernel/Makefile
>
>It also works in all cross-compilation etc. environments.
>And I bet it would work on every platform with very minimal
>changes, if any.

I finally had time to look at sparc64 check_asm.  The code suffers from
several problems:

* It is only built at make dep time so any patches after make dep that
  affect the asm offsets are not picked up.

* The code has to know about all the config options that affect the
  structures, it manually tests for SMP and SPIN_LOCK_DEBUG.  That is
  bad enough but other architectures are much worse, several config
  settings can change the asm offsets, each config setting would have
  to be manually defined.

* The asm output lists all fields in the input structures.  It is
  arguable if this is a good or bad thing, I prefer to explicitly
  define just the symbols required by asm so I view this as a bad
  feature.

* check_asm can only generate offsetof and sizeof fields.  So
  calculated fields like AOFF_task_fpregs have to be done elsewhere.

* The code is complex.  I thought my asm-offsets.c->.s->.h conversion
  was complicated but asm_check takes the cake.

Here is a first cut at doing sparc64 asm offsets the same way that i386
and ia64 are done in kbuild 2.5.

* It uses .c->.s->h so it plugs directly into the kbuild 2.5 dependency
  handling, any patch or config changes that affect asm-offsets.h will
  automatically rebuild asm-offsets.h.

* Only the fields actually used by asm are listed.  I may have missed a
  field or two but gcc will tell us that.

* asm-offsets.c DEFINE() can do any calculation.  So AOFF_task_fpregs
  is now calculated here.

* Less complex :).

* The addition of comments against each define makes the result more
  readable.

==== arch/sparc64/asm-offsets.c ====

/*
 * Generate definitions needed by assembly language modules.
 * This code generates raw asm output which is post-processed to extract
 * and format the required data.
 */

#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/sched.h>

/* Use marker if you need to separate the values later */

#define DEFINE(sym, val, marker) \
  asm volatile("\n-> " #sym " %0 " #val " " #marker : : "i" (val))

#define BLANK() asm volatile("\n->" : : )

int
main(void)
{
  DEFINE(AOFF_mm_context,		offsetof(struct mm_struct, context),);
  BLANK();

  DEFINE(AOFF_task_blocked,		offsetof(struct task_struct, blocked),);
  DEFINE(AOFF_task_egid,		offsetof(struct task_struct, egid),);
  DEFINE(ASIZ_task_egid,		sizeof(((struct task_struct *)NULL)->egid),);
  DEFINE(AOFF_task_euid,		offsetof(struct task_struct, euid),);
  DEFINE(ASIZ_task_euid,		sizeof(((struct task_struct *)NULL)->euid),);
  DEFINE(AOFF_task_flags,		offsetof(struct task_struct, flags),);
  DEFINE(AOFF_task_fpregs,		(sizeof(struct task_struct) + (64 - 1)) & ~(64 - 1),);
  DEFINE(AOFF_task_gid,			offsetof(struct task_struct, gid),);
  DEFINE(ASIZ_task_gid,			sizeof(((struct task_struct *)NULL)->gid),);
  DEFINE(AOFF_task_need_resched,	offsetof(struct task_struct, need_resched),);
  DEFINE(AOFF_task_personality,		offsetof(struct task_struct, personality),);
  DEFINE(ASIZ_task_personality,		sizeof(((struct task_struct *)NULL)->personality),);
  DEFINE(AOFF_task_pid,			offsetof(struct task_struct, pid),);
  DEFINE(AOFF_task_p_opptr,		offsetof(struct task_struct, p_opptr),);
  DEFINE(AOFF_task_processor,		offsetof(struct task_struct, processor),);
  DEFINE(AOFF_task_ptrace,		offsetof(struct task_struct, ptrace),);
  DEFINE(AOFF_task_sigpending,		offsetof(struct task_struct, sigpending),);
  DEFINE(AOFF_task_thread,		offsetof(struct task_struct, thread),);
  DEFINE(AOFF_task_uid,			offsetof(struct task_struct, uid),);
  DEFINE(ASIZ_task_uid,			sizeof(((struct task_struct *)NULL)->uid),);
  BLANK();

  DEFINE(AOFF_thread_current_ds,	offsetof(struct thread_struct, current_ds),);
  DEFINE(AOFF_thread_fault_address,	offsetof(struct thread_struct, fault_address),);
  DEFINE(AOFF_thread_fault_code,	offsetof(struct thread_struct, fault_code),);
  DEFINE(AOFF_thread_flags,		offsetof(struct thread_struct, flags),);
  DEFINE(AOFF_thread_fork_kpsr,		offsetof(struct thread_struct, fork_kpsr),);
  DEFINE(AOFF_thread_fpdepth,		offsetof(struct thread_struct, fpdepth),);
  DEFINE(AOFF_thread_fpsaved,		offsetof(struct thread_struct, fpsaved),);
  DEFINE(AOFF_thread_gsr,		offsetof(struct thread_struct, gsr),);
  DEFINE(AOFF_thread_kernel_cntd0,	offsetof(struct thread_struct, kernel_cntd0),);
  DEFINE(AOFF_thread_pcr_reg,		offsetof(struct thread_struct, pcr_reg),);
  DEFINE(AOFF_thread_reg_window,	offsetof(struct thread_struct, reg_window),);
  DEFINE(AOFF_thread_rwbuf_stkptrs,	offsetof(struct thread_struct, rwbuf_stkptrs),);
  DEFINE(AOFF_thread_use_blkcommit,	offsetof(struct thread_struct, use_blkcommit),);
  DEFINE(AOFF_thread_utraps,		offsetof(struct thread_struct, utraps),);
  DEFINE(AOFF_thread_uwinmask,		offsetof(struct thread_struct, uwinmask),);
  DEFINE(AOFF_thread_w_saved,		offsetof(struct thread_struct, w_saved),);
  DEFINE(AOFF_thread_xfsr,		offsetof(struct thread_struct, xfsr),);

  return 0;
}

==== arch/sparc64/Makefile.in ====

# Convert raw asm offsets into something that can be included as
# assembler definitions.  It converts
#   -> symbol $value source
# into
#   #define symbol value /* 0xvalue source */

user_command(asm-offsets.h
	($(objfile asm-offsets.s))
	(set -e;
	  (echo "#ifndef __ASM_OFFSETS_H__";
	   echo "#define __ASM_OFFSETS_H__";
	   echo "/*";
	   echo " * DO NOT MODIFY";
	   echo " *";
	   echo " * This file was generated by arch/$(ARCH)/Makefile.in.";
	   echo " *";
	   echo " */";
	   echo "";
	   awk "/^->\$$/{printf(\"\\n\");}
	     /^-> /{
	       sym = \$$2;
	       val = \$$3;
	       sub(/^\\\$$/, \"\", val);
	       \$$1 = \"\";
	       \$$2 = \"\";
	       \$$3 = \"\";
	       printf(\"#define %-24s %4d\\t\\t\\t/* 0x%x\\t%s */\\n\",
	         sym, val, val, \$$0)
	     }";
	   echo "";
	   echo "#endif";
	  ) < $< > $@;
	)
	()
	)

==== arch/sparc64/asm-offsets.h output ====

This is partial output and was actually generated on i386 so the
numbers are wrong but it shows what the output will look like.  I do
not have access to a machine for compiling 2.4 sparc64 kernels so none
of the thread values are in this sample.

#ifndef __ASM_OFFSETS_H__
#define __ASM_OFFSETS_H__
/*
 * DO NOT MODIFY
 *
 * This file was generated by arch/sparc64/Makefile.in.
 *
 */

#define AOFF_mm_context           128			/* 0x80	   offsetof(struct mm_struct, context) */

#define AOFF_task_blocked        1632			/* 0x660	   offsetof(struct task_struct, blocked) */
#define AOFF_task_egid            572			/* 0x23c	   offsetof(struct task_struct, egid) */
#define ASIZ_task_egid              4			/* 0x4	   sizeof(((struct task_struct *)NULL)->egid) */
#define AOFF_task_euid            556			/* 0x22c	   offsetof(struct task_struct, euid) */
#define ASIZ_task_euid              4			/* 0x4	   sizeof(((struct task_struct *)NULL)->euid) */
#define AOFF_task_flags             4			/* 0x4	   offsetof(struct task_struct, flags) */
#define AOFF_task_fpregs         1728			/* 0x6c0	   (sizeof(struct task_struct) + (64 - 1)) & ~(64 - 1) */
#define AOFF_task_gid             568			/* 0x238	   offsetof(struct task_struct, gid) */
#define ASIZ_task_gid               4			/* 0x4	   sizeof(((struct task_struct *)NULL)->gid) */
#define AOFF_task_need_resched     20			/* 0x14	   offsetof(struct task_struct, need_resched) */
#define AOFF_task_personality     116			/* 0x74	   offsetof(struct task_struct, personality) */
#define ASIZ_task_personality       4			/* 0x4	   sizeof(((struct task_struct *)NULL)->personality) */
#define AOFF_task_pid             124			/* 0x7c	   offsetof(struct task_struct, pid) */
#define AOFF_task_p_opptr         148			/* 0x94	   offsetof(struct task_struct, p_opptr) */
#define AOFF_task_processor        52			/* 0x34	   offsetof(struct task_struct, processor) */
#define AOFF_task_ptrace           24			/* 0x18	   offsetof(struct task_struct, ptrace) */
#define AOFF_task_sigpending        8			/* 0x8	   offsetof(struct task_struct, sigpending) */
#define AOFF_task_thread          880			/* 0x370	   offsetof(struct task_struct, thread) */
#define AOFF_task_uid             552			/* 0x228	   offsetof(struct task_struct, uid) */
#define ASIZ_task_uid               4			/* 0x4	   sizeof(((struct task_struct *)NULL)->uid) */

/* Thread values would be here if I could compile for sparc64. */

#endif


      parent reply	other threads:[~2001-10-14 11:27 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-10-04 11:47 [RFC] Standard way of generating assembler offsets Keith Owens
2001-10-04 15:36 ` george anzinger
2001-10-05  5:48   ` Keith Owens
2001-10-06  5:21 ` Keith Owens
2001-10-08  9:35 ` Pantelis Antoniou
2001-10-08 17:29   ` george anzinger
2001-10-08 17:56   ` Georg Nikodym
2001-10-08 19:00     ` george anzinger
2001-10-09  7:38       ` Pantelis Antoniou
2001-10-09  9:28       ` David S. Miller
2001-10-08  9:49 ` David S. Miller
2001-10-09  7:25   ` Pantelis Antoniou
2001-10-09  9:24   ` David S. Miller
2001-10-14 11:27   ` Keith Owens [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1519.1003058839@ocs3.intra.ocs.com.au \
    --to=kaos@ocs.com.au \
    --cc=davem@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).