* [patch 1/4] x86: _end symbol missing from Symbol.map
@ 2009-11-04 15:19 akpm
2009-11-08 11:07 ` [tip:x86/urgent] x86: Add back _end symbol that is " tip-bot for Hannes Reinecke
0 siblings, 1 reply; 9+ messages in thread
From: akpm @ 2009-11-04 15:19 UTC (permalink / raw)
To: linux-kbuild; +Cc: akpm, hare, mingo, sam, stable
From: Hannes Reinecke <hare@suse.de>
With 2.6.31 'crash' on x86_64 falls flat on its face as the '_end' symbol
is missing from the System.map file.
The culprit is commit 091e52c3551d3031343df24b573b770b4c6c72b6, which
moved the '_end' symbol into it's own section. Apparently this causes
kallsyms to not reference it properly.
So either we'd need to revert part of the patch to not include _end in
it's own section.
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
arch/x86/kernel/vmlinux.lds.S | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff -puN arch/x86/kernel/vmlinux.lds.S~x86-_end-symbol-missing-from-symbolmap arch/x86/kernel/vmlinux.lds.S
--- a/arch/x86/kernel/vmlinux.lds.S~x86-_end-symbol-missing-from-symbolmap
+++ a/arch/x86/kernel/vmlinux.lds.S
@@ -319,9 +319,7 @@ SECTIONS
__brk_limit = .;
}
- .end : AT(ADDR(.end) - LOAD_OFFSET) {
- _end = .;
- }
+ _end = .;
STABS_DEBUG
DWARF_DEBUG
_
^ permalink raw reply [flat|nested] 9+ messages in thread* [tip:x86/urgent] x86: Add back _end symbol that is missing from Symbol.map 2009-11-04 15:19 [patch 1/4] x86: _end symbol missing from Symbol.map akpm @ 2009-11-08 11:07 ` tip-bot for Hannes Reinecke 2009-11-08 11:38 ` Sam Ravnborg 0 siblings, 1 reply; 9+ messages in thread From: tip-bot for Hannes Reinecke @ 2009-11-08 11:07 UTC (permalink / raw) To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, sam, akpm, hare, tglx, mingo Commit-ID: d1e4d37b79e944f6351ae38eb1ca7c9f7b506e76 Gitweb: http://git.kernel.org/tip/d1e4d37b79e944f6351ae38eb1ca7c9f7b506e76 Author: Hannes Reinecke <hare@suse.de> AuthorDate: Wed, 4 Nov 2009 07:19:32 -0800 Committer: Ingo Molnar <mingo@elte.hu> CommitDate: Sun, 8 Nov 2009 12:05:03 +0100 x86: Add back _end symbol that is missing from Symbol.map With 2.6.31 'crash' on x86_64 falls flat on its face as the '_end' symbol is missing from the System.map file. The culprit is commit 091e52c3551d3031343df24b573b770b4c6c72b6, which moved the '_end' symbol into it's own section. Apparently this causes kallsyms to not reference it properly. So do not include _end in it's own section. Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Cc: Sam Ravnborg <sam@ravnborg.org> Cc: <stable@kernel.org> # .31.x LKML-Reference: <200911041519.nA4FJWEW030164@imap1.linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> --- arch/x86/kernel/vmlinux.lds.S | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 3c68fe2..b2f811d 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -291,9 +291,7 @@ SECTIONS __brk_limit = .; } - .end : AT(ADDR(.end) - LOAD_OFFSET) { - _end = .; - } + _end = .; STABS_DEBUG DWARF_DEBUG ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [tip:x86/urgent] x86: Add back _end symbol that is missing from Symbol.map 2009-11-08 11:07 ` [tip:x86/urgent] x86: Add back _end symbol that is " tip-bot for Hannes Reinecke @ 2009-11-08 11:38 ` Sam Ravnborg 2009-11-08 11:48 ` Ingo Molnar 2009-11-08 16:36 ` [tip:x86/urgent] x86: Add back _end symbol that is missing from Symbol.map H. Peter Anvin 0 siblings, 2 replies; 9+ messages in thread From: Sam Ravnborg @ 2009-11-08 11:38 UTC (permalink / raw) To: mingo, hpa, linux-kernel, hare, akpm, tglx, mingo; +Cc: linux-tip-commits On Sun, Nov 08, 2009 at 11:07:12AM +0000, tip-bot for Hannes Reinecke wrote: > Commit-ID: d1e4d37b79e944f6351ae38eb1ca7c9f7b506e76 > Gitweb: http://git.kernel.org/tip/d1e4d37b79e944f6351ae38eb1ca7c9f7b506e76 > Author: Hannes Reinecke <hare@suse.de> > AuthorDate: Wed, 4 Nov 2009 07:19:32 -0800 > Committer: Ingo Molnar <mingo@elte.hu> > CommitDate: Sun, 8 Nov 2009 12:05:03 +0100 > > x86: Add back _end symbol that is missing from Symbol.map > > With 2.6.31 'crash' on x86_64 falls flat on its face as the > '_end' symbol is missing from the System.map file. > > The culprit is commit 091e52c3551d3031343df24b573b770b4c6c72b6, > which moved the '_end' symbol into it's own section. Apparently > this causes kallsyms to not reference it properly. > > So do not include _end in it's own section. > > Signed-off-by: Andrew Morton <akpm@linux-foundation.org> > Cc: Sam Ravnborg <sam@ravnborg.org> > Cc: <stable@kernel.org> # .31.x > LKML-Reference: <200911041519.nA4FJWEW030164@imap1.linux-foundation.org> > Signed-off-by: Ingo Molnar <mingo@elte.hu> I'm afraid this will break a RELOCTABLE i386 kernel. We fixed this up some time ago where we had to move the symbol definition inside a section to prevent the symbol being absolute. Sam ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [tip:x86/urgent] x86: Add back _end symbol that is missing from Symbol.map 2009-11-08 11:38 ` Sam Ravnborg @ 2009-11-08 11:48 ` Ingo Molnar 2009-11-08 12:38 ` Sam Ravnborg 2009-11-08 16:36 ` [tip:x86/urgent] x86: Add back _end symbol that is missing from Symbol.map H. Peter Anvin 1 sibling, 1 reply; 9+ messages in thread From: Ingo Molnar @ 2009-11-08 11:48 UTC (permalink / raw) To: Sam Ravnborg Cc: mingo, hpa, linux-kernel, hare, akpm, tglx, linux-tip-commits * Sam Ravnborg <sam@ravnborg.org> wrote: > On Sun, Nov 08, 2009 at 11:07:12AM +0000, tip-bot for Hannes Reinecke wrote: > > Commit-ID: d1e4d37b79e944f6351ae38eb1ca7c9f7b506e76 > > Gitweb: http://git.kernel.org/tip/d1e4d37b79e944f6351ae38eb1ca7c9f7b506e76 > > Author: Hannes Reinecke <hare@suse.de> > > AuthorDate: Wed, 4 Nov 2009 07:19:32 -0800 > > Committer: Ingo Molnar <mingo@elte.hu> > > CommitDate: Sun, 8 Nov 2009 12:05:03 +0100 > > > > x86: Add back _end symbol that is missing from Symbol.map > > > > With 2.6.31 'crash' on x86_64 falls flat on its face as the > > '_end' symbol is missing from the System.map file. > > > > The culprit is commit 091e52c3551d3031343df24b573b770b4c6c72b6, > > which moved the '_end' symbol into it's own section. Apparently > > this causes kallsyms to not reference it properly. > > > > So do not include _end in it's own section. > > > > Signed-off-by: Andrew Morton <akpm@linux-foundation.org> > > Cc: Sam Ravnborg <sam@ravnborg.org> > > Cc: <stable@kernel.org> # .31.x > > LKML-Reference: <200911041519.nA4FJWEW030164@imap1.linux-foundation.org> > > Signed-off-by: Ingo Molnar <mingo@elte.hu> > > I'm afraid this will break a RELOCTABLE i386 kernel. > > We fixed this up some time ago where we had to > move the symbol definition inside a section > to prevent the symbol being absolute. ah, indeed. So ... the question is then, why did _end disappear from System.map? Ingo ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [tip:x86/urgent] x86: Add back _end symbol that is missing from Symbol.map 2009-11-08 11:48 ` Ingo Molnar @ 2009-11-08 12:38 ` Sam Ravnborg 2009-11-08 12:42 ` Ingo Molnar 2009-11-09 18:40 ` H. Peter Anvin 0 siblings, 2 replies; 9+ messages in thread From: Sam Ravnborg @ 2009-11-08 12:38 UTC (permalink / raw) To: Ingo Molnar; +Cc: mingo, hpa, linux-kernel, hare, akpm, tglx, linux-tip-commits On Sun, Nov 08, 2009 at 12:48:29PM +0100, Ingo Molnar wrote: > > * Sam Ravnborg <sam@ravnborg.org> wrote: > > > On Sun, Nov 08, 2009 at 11:07:12AM +0000, tip-bot for Hannes Reinecke wrote: > > > Commit-ID: d1e4d37b79e944f6351ae38eb1ca7c9f7b506e76 > > > Gitweb: http://git.kernel.org/tip/d1e4d37b79e944f6351ae38eb1ca7c9f7b506e76 > > > Author: Hannes Reinecke <hare@suse.de> > > > AuthorDate: Wed, 4 Nov 2009 07:19:32 -0800 > > > Committer: Ingo Molnar <mingo@elte.hu> > > > CommitDate: Sun, 8 Nov 2009 12:05:03 +0100 > > > > > > x86: Add back _end symbol that is missing from Symbol.map > > > > > > With 2.6.31 'crash' on x86_64 falls flat on its face as the > > > '_end' symbol is missing from the System.map file. > > > > > > The culprit is commit 091e52c3551d3031343df24b573b770b4c6c72b6, > > > which moved the '_end' symbol into it's own section. Apparently > > > this causes kallsyms to not reference it properly. > > > > > > So do not include _end in it's own section. > > > > > > Signed-off-by: Andrew Morton <akpm@linux-foundation.org> > > > Cc: Sam Ravnborg <sam@ravnborg.org> > > > Cc: <stable@kernel.org> # .31.x > > > LKML-Reference: <200911041519.nA4FJWEW030164@imap1.linux-foundation.org> > > > Signed-off-by: Ingo Molnar <mingo@elte.hu> > > > > I'm afraid this will break a RELOCTABLE i386 kernel. > > > > We fixed this up some time ago where we had to > > move the symbol definition inside a section > > to prevent the symbol being absolute. > > ah, indeed. So ... the question is then, why did _end disappear from > System.map? I think ld discards zero size sections. No need to keep them around if they are empty. Following patch should fix it up in a better way. I reused most of Hannes changelog. Sam [PATCH] x86: Add back _end symbol that is missing from Symbol.map With 2.6.31 'crash' on x86_64 falls flat on its face as the '_end' symbol is missing from the System.map file. The culprit is commit 091e52c3551d3031343df24b573b770b4c6c72b6, which moved the '_end' symbol into it's own section. The problem is likely that ld discards empty sections. So move the definition of _end into the last section defined. Cc: Hannes Reinecke <hare@suse.de> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: <stable@kernel.org> # .31.x Signed-off-by: Sam Ravnborg <sam@ravnborg.org> diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 92929fb..c58a6e3 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -289,9 +289,12 @@ SECTIONS . += 64 * 1024; /* 64k alignment slop space */ *(.brk_reservation) /* areas brk users have reserved */ __brk_limit = .; - } - .end : AT(ADDR(.end) - LOAD_OFFSET) { + /* + * To support RELOCTABLE kernel _end must be inside a section. + * And ld is know to discard empty section so we locate _end in + * last section we define. + */ _end = .; } ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [tip:x86/urgent] x86: Add back _end symbol that is missing from Symbol.map 2009-11-08 12:38 ` Sam Ravnborg @ 2009-11-08 12:42 ` Ingo Molnar 2009-11-09 18:40 ` H. Peter Anvin 1 sibling, 0 replies; 9+ messages in thread From: Ingo Molnar @ 2009-11-08 12:42 UTC (permalink / raw) To: Sam Ravnborg Cc: mingo, hpa, linux-kernel, hare, akpm, tglx, linux-tip-commits * Sam Ravnborg <sam@ravnborg.org> wrote: > On Sun, Nov 08, 2009 at 12:48:29PM +0100, Ingo Molnar wrote: > > > > * Sam Ravnborg <sam@ravnborg.org> wrote: > > > > > On Sun, Nov 08, 2009 at 11:07:12AM +0000, tip-bot for Hannes Reinecke wrote: > > > > Commit-ID: d1e4d37b79e944f6351ae38eb1ca7c9f7b506e76 > > > > Gitweb: http://git.kernel.org/tip/d1e4d37b79e944f6351ae38eb1ca7c9f7b506e76 > > > > Author: Hannes Reinecke <hare@suse.de> > > > > AuthorDate: Wed, 4 Nov 2009 07:19:32 -0800 > > > > Committer: Ingo Molnar <mingo@elte.hu> > > > > CommitDate: Sun, 8 Nov 2009 12:05:03 +0100 > > > > > > > > x86: Add back _end symbol that is missing from Symbol.map > > > > > > > > With 2.6.31 'crash' on x86_64 falls flat on its face as the > > > > '_end' symbol is missing from the System.map file. > > > > > > > > The culprit is commit 091e52c3551d3031343df24b573b770b4c6c72b6, > > > > which moved the '_end' symbol into it's own section. Apparently > > > > this causes kallsyms to not reference it properly. > > > > > > > > So do not include _end in it's own section. > > > > > > > > Signed-off-by: Andrew Morton <akpm@linux-foundation.org> > > > > Cc: Sam Ravnborg <sam@ravnborg.org> > > > > Cc: <stable@kernel.org> # .31.x > > > > LKML-Reference: <200911041519.nA4FJWEW030164@imap1.linux-foundation.org> > > > > Signed-off-by: Ingo Molnar <mingo@elte.hu> > > > > > > I'm afraid this will break a RELOCTABLE i386 kernel. > > > > > > We fixed this up some time ago where we had to > > > move the symbol definition inside a section > > > to prevent the symbol being absolute. > > > > ah, indeed. So ... the question is then, why did _end disappear from > > System.map? > > I think ld discards zero size sections. No need to keep them around if > they are empty. > > Following patch should fix it up in a better way. thanks Sam, that was fast! > I reused most of Hannes changelog. Hannes, if it works for you then please resend the patch with your signoff so we can send it upstream-wards. Thanks, Ingo ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [tip:x86/urgent] x86: Add back _end symbol that is missing from Symbol.map 2009-11-08 12:38 ` Sam Ravnborg 2009-11-08 12:42 ` Ingo Molnar @ 2009-11-09 18:40 ` H. Peter Anvin 2009-12-14 22:27 ` [tip:x86/urgent] x86: Regex support and known-movable symbols for relocs, fix _end tip-bot for H. Peter Anvin 1 sibling, 1 reply; 9+ messages in thread From: H. Peter Anvin @ 2009-11-09 18:40 UTC (permalink / raw) To: Sam Ravnborg Cc: Ingo Molnar, mingo, linux-kernel, hare, akpm, tglx, linux-tip-commits [-- Attachment #1: Type: text/plain, Size: 879 bytes --] On 11/08/2009 04:38 AM, Sam Ravnborg wrote: > I think ld discards zero size sections. No need to keep them around > if they are empty. > > Following patch should fix it up in a better way. > I reused most of Hannes changelog. Part of me wonders if this isn't better handled by just making relocs.c deal with _end as a special case (and of course making it possible to add others.) Here is a distinctively non-minimal patch -- I used a modified version of relocs.c for the Syslinux project, and this is basically a backport of the changes I did for that. It uses a regex to match either known-absolute or known-relative symbols; the remaining changes are mostly just dealing with particularly stupid code like using printf() to do the work of fwrite(), and using select() where appropriate. Sam, Ingo: I'd appreciate your opinions before checking anything in on this. -hpa [-- Attachment #2: diff --] [-- Type: text/plain, Size: 4867 bytes --] diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c index bbeb0c3..89bbf4e 100644 --- a/arch/x86/boot/compressed/relocs.c +++ b/arch/x86/boot/compressed/relocs.c @@ -9,6 +9,9 @@ #include <byteswap.h> #define USE_BSD #include <endian.h> +#include <regex.h> + +static void die(char *fmt, ...); #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) static Elf32_Ehdr ehdr; @@ -30,25 +33,47 @@ static struct section *secs; * the address for which it has been compiled. Don't warn user about * absolute relocations present w.r.t these symbols. */ -static const char* safe_abs_relocs[] = { - "xen_irq_disable_direct_reloc", - "xen_save_fl_direct_reloc", -}; +static const char abs_sym_regex[] = + "^(xen_irq_disable_direct_reloc$|" + "xen_save_fl_direct_reloc$|" + "VDSO|" + "__crc_)"; +static regex_t abs_sym_regex_c; +static int is_abs_reloc(const char *sym_name) +{ + return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0); +} -static int is_safe_abs_reloc(const char* sym_name) +/* + * These symbols are known to be relative, even if the linker marks them + * as absolute (typically defined outside any section in the linker script.) + */ +static const char rel_sym_regex[] = + "^_end$"; +static regex_t rel_sym_regex_c; +static int is_rel_reloc(const char *sym_name) { - int i; + return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0); +} - for (i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) { - if (!strcmp(sym_name, safe_abs_relocs[i])) - /* Match found */ - return 1; - } - if (strncmp(sym_name, "VDSO", 4) == 0) - return 1; - if (strncmp(sym_name, "__crc_", 6) == 0) - return 1; - return 0; +static void regex_init(void) +{ + char errbuf[128]; + int err; + + err = regcomp(&abs_sym_regex_c, abs_sym_regex, + REG_EXTENDED|REG_NOSUB); + if (err) { + regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf); + die("%s", errbuf); + } + + err = regcomp(&rel_sym_regex_c, rel_sym_regex, + REG_EXTENDED|REG_NOSUB); + if (err) { + regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf); + die("%s", errbuf); + } } static void die(char *fmt, ...) @@ -131,7 +156,7 @@ static const char *rel_type(unsigned type) #undef REL_TYPE }; const char *name = "unknown type rel type name"; - if (type < ARRAY_SIZE(type_name)) { + if (type < ARRAY_SIZE(type_name) && type_name[type]) { name = type_name[type]; } return name; @@ -448,7 +473,7 @@ static void print_absolute_relocs(void) * Before warning check if this absolute symbol * relocation is harmless. */ - if (is_safe_abs_reloc(name)) + if (is_abs_reloc(name) || is_rel_reloc(name)) continue; if (!printed) { @@ -501,21 +526,26 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; r_type = ELF32_R_TYPE(rel->r_info); /* Don't visit relocations to absolute symbols */ - if (sym->st_shndx == SHN_ABS) { + if (sym->st_shndx == SHN_ABS && + !is_rel_reloc(sym_name(sym_strtab, sym))) { continue; } - if (r_type == R_386_NONE || r_type == R_386_PC32) { + switch (r_type) { + case R_386_NONE: + case R_386_PC32: /* * NONE can be ignored and and PC relative * relocations don't need to be adjusted. */ - } - else if (r_type == R_386_32) { + break; + case R_386_32: /* Visit relocations that need to be adjusted */ visit(rel, sym); - } - else { - die("Unsupported relocation type: %d\n", r_type); + break; + default: + die("Unsupported relocation type: %s (%d)\n", + rel_type(r_type), r_type); + break; } } } @@ -571,16 +601,15 @@ static void emit_relocs(int as_text) } else { unsigned char buf[4]; - buf[0] = buf[1] = buf[2] = buf[3] = 0; /* Print a stop */ - printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); + fwrite("\0\0\0\0", 4, 1, stdout); /* Now print each relocation */ for (i = 0; i < reloc_count; i++) { buf[0] = (relocs[i] >> 0) & 0xff; buf[1] = (relocs[i] >> 8) & 0xff; buf[2] = (relocs[i] >> 16) & 0xff; buf[3] = (relocs[i] >> 24) & 0xff; - printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); + fwrite(buf, 4, 1, stdout); } } } @@ -598,6 +627,8 @@ int main(int argc, char **argv) FILE *fp; int i; + regex_init(); + show_absolute_syms = 0; show_absolute_relocs = 0; as_text = 0; diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 3c68fe2..b2f811d 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -291,9 +291,7 @@ SECTIONS __brk_limit = .; } - .end : AT(ADDR(.end) - LOAD_OFFSET) { - _end = .; - } + _end = .; STABS_DEBUG DWARF_DEBUG ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [tip:x86/urgent] x86: Regex support and known-movable symbols for relocs, fix _end 2009-11-09 18:40 ` H. Peter Anvin @ 2009-12-14 22:27 ` tip-bot for H. Peter Anvin 0 siblings, 0 replies; 9+ messages in thread From: tip-bot for H. Peter Anvin @ 2009-12-14 22:27 UTC (permalink / raw) To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, mmarek, tglx, sedat.dilek Commit-ID: 873b5271f878a11729fb4602c6ce967d0ff81119 Gitweb: http://git.kernel.org/tip/873b5271f878a11729fb4602c6ce967d0ff81119 Author: H. Peter Anvin <hpa@zytor.com> AuthorDate: Mon, 14 Dec 2009 13:55:20 -0800 Committer: H. Peter Anvin <hpa@zytor.com> CommitDate: Mon, 14 Dec 2009 13:55:20 -0800 x86: Regex support and known-movable symbols for relocs, fix _end This adds a new category of symbols to the relocs program: symbols which are known to be relative, even though the linker emits them as absolute; this is the case for symbols that live in the linker script, which currently applies to _end. Unfortunately the previous workaround of putting _end in its own empty section was defeated by newer binutils, which remove empty sections completely. This patch also changes the symbol matching to use regular expressions instead of hardcoded C for specific patterns. This is a decidedly non-minimal patch: a modified version of the relocs program is used as part of the Syslinux build, and this is basically a backport to Linux of some of those changes; they have thus been well tested. Signed-off-by: H. Peter Anvin <hpa@zytor.com> LKML-Reference: <4AF86211.3070103@zytor.com> Acked-by: Michal Marek <mmarek@suse.cz> Tested-by: Sedat Dilek <sedat.dilek@gmail.com> --- arch/x86/boot/compressed/relocs.c | 87 +++++++++++++++++++++++++------------ arch/x86/kernel/vmlinux.lds.S | 4 +- 2 files changed, 60 insertions(+), 31 deletions(-) diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c index bbeb0c3..89bbf4e 100644 --- a/arch/x86/boot/compressed/relocs.c +++ b/arch/x86/boot/compressed/relocs.c @@ -9,6 +9,9 @@ #include <byteswap.h> #define USE_BSD #include <endian.h> +#include <regex.h> + +static void die(char *fmt, ...); #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) static Elf32_Ehdr ehdr; @@ -30,25 +33,47 @@ static struct section *secs; * the address for which it has been compiled. Don't warn user about * absolute relocations present w.r.t these symbols. */ -static const char* safe_abs_relocs[] = { - "xen_irq_disable_direct_reloc", - "xen_save_fl_direct_reloc", -}; +static const char abs_sym_regex[] = + "^(xen_irq_disable_direct_reloc$|" + "xen_save_fl_direct_reloc$|" + "VDSO|" + "__crc_)"; +static regex_t abs_sym_regex_c; +static int is_abs_reloc(const char *sym_name) +{ + return !regexec(&abs_sym_regex_c, sym_name, 0, NULL, 0); +} -static int is_safe_abs_reloc(const char* sym_name) +/* + * These symbols are known to be relative, even if the linker marks them + * as absolute (typically defined outside any section in the linker script.) + */ +static const char rel_sym_regex[] = + "^_end$"; +static regex_t rel_sym_regex_c; +static int is_rel_reloc(const char *sym_name) { - int i; + return !regexec(&rel_sym_regex_c, sym_name, 0, NULL, 0); +} - for (i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) { - if (!strcmp(sym_name, safe_abs_relocs[i])) - /* Match found */ - return 1; - } - if (strncmp(sym_name, "VDSO", 4) == 0) - return 1; - if (strncmp(sym_name, "__crc_", 6) == 0) - return 1; - return 0; +static void regex_init(void) +{ + char errbuf[128]; + int err; + + err = regcomp(&abs_sym_regex_c, abs_sym_regex, + REG_EXTENDED|REG_NOSUB); + if (err) { + regerror(err, &abs_sym_regex_c, errbuf, sizeof errbuf); + die("%s", errbuf); + } + + err = regcomp(&rel_sym_regex_c, rel_sym_regex, + REG_EXTENDED|REG_NOSUB); + if (err) { + regerror(err, &rel_sym_regex_c, errbuf, sizeof errbuf); + die("%s", errbuf); + } } static void die(char *fmt, ...) @@ -131,7 +156,7 @@ static const char *rel_type(unsigned type) #undef REL_TYPE }; const char *name = "unknown type rel type name"; - if (type < ARRAY_SIZE(type_name)) { + if (type < ARRAY_SIZE(type_name) && type_name[type]) { name = type_name[type]; } return name; @@ -448,7 +473,7 @@ static void print_absolute_relocs(void) * Before warning check if this absolute symbol * relocation is harmless. */ - if (is_safe_abs_reloc(name)) + if (is_abs_reloc(name) || is_rel_reloc(name)) continue; if (!printed) { @@ -501,21 +526,26 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; r_type = ELF32_R_TYPE(rel->r_info); /* Don't visit relocations to absolute symbols */ - if (sym->st_shndx == SHN_ABS) { + if (sym->st_shndx == SHN_ABS && + !is_rel_reloc(sym_name(sym_strtab, sym))) { continue; } - if (r_type == R_386_NONE || r_type == R_386_PC32) { + switch (r_type) { + case R_386_NONE: + case R_386_PC32: /* * NONE can be ignored and and PC relative * relocations don't need to be adjusted. */ - } - else if (r_type == R_386_32) { + break; + case R_386_32: /* Visit relocations that need to be adjusted */ visit(rel, sym); - } - else { - die("Unsupported relocation type: %d\n", r_type); + break; + default: + die("Unsupported relocation type: %s (%d)\n", + rel_type(r_type), r_type); + break; } } } @@ -571,16 +601,15 @@ static void emit_relocs(int as_text) } else { unsigned char buf[4]; - buf[0] = buf[1] = buf[2] = buf[3] = 0; /* Print a stop */ - printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); + fwrite("\0\0\0\0", 4, 1, stdout); /* Now print each relocation */ for (i = 0; i < reloc_count; i++) { buf[0] = (relocs[i] >> 0) & 0xff; buf[1] = (relocs[i] >> 8) & 0xff; buf[2] = (relocs[i] >> 16) & 0xff; buf[3] = (relocs[i] >> 24) & 0xff; - printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); + fwrite(buf, 4, 1, stdout); } } } @@ -598,6 +627,8 @@ int main(int argc, char **argv) FILE *fp; int i; + regex_init(); + show_absolute_syms = 0; show_absolute_relocs = 0; as_text = 0; diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index f3f2104..f92a0da 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -319,9 +319,7 @@ SECTIONS __brk_limit = .; } - .end : AT(ADDR(.end) - LOAD_OFFSET) { - _end = .; - } + _end = .; STABS_DEBUG DWARF_DEBUG ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [tip:x86/urgent] x86: Add back _end symbol that is missing from Symbol.map 2009-11-08 11:38 ` Sam Ravnborg 2009-11-08 11:48 ` Ingo Molnar @ 2009-11-08 16:36 ` H. Peter Anvin 1 sibling, 0 replies; 9+ messages in thread From: H. Peter Anvin @ 2009-11-08 16:36 UTC (permalink / raw) To: Sam Ravnborg Cc: mingo, linux-kernel, hare, akpm, tglx, mingo, linux-tip-commits On 11/08/2009 03:38 AM, Sam Ravnborg wrote: > > I'm afraid this will break a RELOCTABLE i386 kernel. > > We fixed this up some time ago where we had to > move the symbol definition inside a section > to prevent the symbol being absolute. > It's also possible to have a whitelist of "known relative" symbols in reloc.c, just as we have a blacklist of "known absolute" symbols. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-12-14 22:28 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-11-04 15:19 [patch 1/4] x86: _end symbol missing from Symbol.map akpm 2009-11-08 11:07 ` [tip:x86/urgent] x86: Add back _end symbol that is " tip-bot for Hannes Reinecke 2009-11-08 11:38 ` Sam Ravnborg 2009-11-08 11:48 ` Ingo Molnar 2009-11-08 12:38 ` Sam Ravnborg 2009-11-08 12:42 ` Ingo Molnar 2009-11-09 18:40 ` H. Peter Anvin 2009-12-14 22:27 ` [tip:x86/urgent] x86: Regex support and known-movable symbols for relocs, fix _end tip-bot for H. Peter Anvin 2009-11-08 16:36 ` [tip:x86/urgent] x86: Add back _end symbol that is missing from Symbol.map H. Peter Anvin
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.