Messages in this thread |  | | From | Keith Owens <> | Subject | Re: [RFC] Standard way of generating assembler offsets | Date | Sun, 14 Oct 2001 21:27:19 +1000 |
| |
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
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |