diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-11-12 00:09:58 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-11-12 00:09:58 +0000 |
commit | 1ad4db1d8e47b8835f19ad8fe44475db51cf01f9 (patch) | |
tree | 69ced31a88277c8089093830d45df57217ad47bf /modutils/modutils-24.c | |
parent | f91f14d2211148ade28270572b9c45023f9b6580 (diff) | |
download | busybox-w32-1ad4db1d8e47b8835f19ad8fe44475db51cf01f9.tar.gz busybox-w32-1ad4db1d8e47b8835f19ad8fe44475db51cf01f9.tar.bz2 busybox-w32-1ad4db1d8e47b8835f19ad8fe44475db51cf01f9.zip |
modprobe-small: fix failure to load when no arguments are given
modutils-24: fix bad interaction of xzalloc with xrealloc_vector; style fixes
Diffstat (limited to 'modutils/modutils-24.c')
-rw-r--r-- | modutils/modutils-24.c | 90 |
1 files changed, 52 insertions, 38 deletions
diff --git a/modutils/modutils-24.c b/modutils/modutils-24.c index 2bc4bda92..ae0afd44c 100644 --- a/modutils/modutils-24.c +++ b/modutils/modutils-24.c | |||
@@ -997,8 +997,9 @@ arch_apply_relocation(struct obj_file *f, | |||
997 | 997 | ||
998 | case R_68K_PC8: | 998 | case R_68K_PC8: |
999 | v -= dot; | 999 | v -= dot; |
1000 | if ((ElfW(Sword))v > 0x7f || | 1000 | if ((ElfW(Sword))v > 0x7f |
1001 | (ElfW(Sword))v < -(ElfW(Sword))0x80) { | 1001 | || (ElfW(Sword))v < -(ElfW(Sword))0x80 |
1002 | ) { | ||
1002 | ret = obj_reloc_overflow; | 1003 | ret = obj_reloc_overflow; |
1003 | } | 1004 | } |
1004 | *(char *)loc = v; | 1005 | *(char *)loc = v; |
@@ -1006,8 +1007,9 @@ arch_apply_relocation(struct obj_file *f, | |||
1006 | 1007 | ||
1007 | case R_68K_PC16: | 1008 | case R_68K_PC16: |
1008 | v -= dot; | 1009 | v -= dot; |
1009 | if ((ElfW(Sword))v > 0x7fff || | 1010 | if ((ElfW(Sword))v > 0x7fff |
1010 | (ElfW(Sword))v < -(ElfW(Sword))0x8000) { | 1011 | || (ElfW(Sword))v < -(ElfW(Sword))0x8000 |
1012 | ) { | ||
1011 | ret = obj_reloc_overflow; | 1013 | ret = obj_reloc_overflow; |
1012 | } | 1014 | } |
1013 | *(short *)loc = v; | 1015 | *(short *)loc = v; |
@@ -1146,8 +1148,9 @@ arch_apply_relocation(struct obj_file *f, | |||
1146 | { | 1148 | { |
1147 | Elf32_Addr word; | 1149 | Elf32_Addr word; |
1148 | 1150 | ||
1149 | if ((Elf32_Sword)v > 0x7fff || | 1151 | if ((Elf32_Sword)v > 0x7fff |
1150 | (Elf32_Sword)v < -(Elf32_Sword)0x8000) { | 1152 | || (Elf32_Sword)v < -(Elf32_Sword)0x8000 |
1153 | ) { | ||
1151 | ret = obj_reloc_overflow; | 1154 | ret = obj_reloc_overflow; |
1152 | } | 1155 | } |
1153 | 1156 | ||
@@ -1176,8 +1179,9 @@ arch_apply_relocation(struct obj_file *f, | |||
1176 | Elf32_Addr word; | 1179 | Elf32_Addr word; |
1177 | 1180 | ||
1178 | v -= dot + 4; | 1181 | v -= dot + 4; |
1179 | if ((Elf32_Sword)v > 0x7fff || | 1182 | if ((Elf32_Sword)v > 0x7fff |
1180 | (Elf32_Sword)v < -(Elf32_Sword)0x8000) { | 1183 | || (Elf32_Sword)v < -(Elf32_Sword)0x8000 |
1184 | ) { | ||
1181 | ret = obj_reloc_overflow; | 1185 | ret = obj_reloc_overflow; |
1182 | } | 1186 | } |
1183 | 1187 | ||
@@ -1191,9 +1195,10 @@ arch_apply_relocation(struct obj_file *f, | |||
1191 | Elf32_Addr word, gp; | 1195 | Elf32_Addr word, gp; |
1192 | /* get _gp */ | 1196 | /* get _gp */ |
1193 | gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp")); | 1197 | gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp")); |
1194 | v-=gp; | 1198 | v -= gp; |
1195 | if ((Elf32_Sword)v > 0x7fff || | 1199 | if ((Elf32_Sword)v > 0x7fff |
1196 | (Elf32_Sword)v < -(Elf32_Sword)0x8000) { | 1200 | || (Elf32_Sword)v < -(Elf32_Sword)0x8000 |
1201 | ) { | ||
1197 | ret = obj_reloc_overflow; | 1202 | ret = obj_reloc_overflow; |
1198 | } | 1203 | } |
1199 | 1204 | ||
@@ -2070,7 +2075,6 @@ obj_find_symbol(struct obj_file *f, const char *name) | |||
2070 | for (sym = f->symtab[hash]; sym; sym = sym->next) | 2075 | for (sym = f->symtab[hash]; sym; sym = sym->next) |
2071 | if (f->symbol_cmp(sym->name, name) == 0) | 2076 | if (f->symbol_cmp(sym->name, name) == 0) |
2072 | return sym; | 2077 | return sym; |
2073 | |||
2074 | return NULL; | 2078 | return NULL; |
2075 | } | 2079 | } |
2076 | 2080 | ||
@@ -2079,12 +2083,10 @@ static ElfW(Addr) obj_symbol_final_value(struct obj_file * f, struct obj_symbol | |||
2079 | if (sym) { | 2083 | if (sym) { |
2080 | if (sym->secidx >= SHN_LORESERVE) | 2084 | if (sym->secidx >= SHN_LORESERVE) |
2081 | return sym->value; | 2085 | return sym->value; |
2082 | |||
2083 | return sym->value + f->sections[sym->secidx]->header.sh_addr; | 2086 | return sym->value + f->sections[sym->secidx]->header.sh_addr; |
2084 | } else { | ||
2085 | /* As a special case, a NULL sym has value zero. */ | ||
2086 | return 0; | ||
2087 | } | 2087 | } |
2088 | /* As a special case, a NULL sym has value zero. */ | ||
2089 | return 0; | ||
2088 | } | 2090 | } |
2089 | 2091 | ||
2090 | static struct obj_section *obj_find_section(struct obj_file *f, const char *name) | 2092 | static struct obj_section *obj_find_section(struct obj_file *f, const char *name) |
@@ -2094,7 +2096,6 @@ static struct obj_section *obj_find_section(struct obj_file *f, const char *name | |||
2094 | for (i = 0; i < n; ++i) | 2096 | for (i = 0; i < n; ++i) |
2095 | if (strcmp(f->sections[i]->name, name) == 0) | 2097 | if (strcmp(f->sections[i]->name, name) == 0) |
2096 | return f->sections[i]; | 2098 | return f->sections[i]; |
2097 | |||
2098 | return NULL; | 2099 | return NULL; |
2099 | } | 2100 | } |
2100 | 2101 | ||
@@ -2105,9 +2106,11 @@ static int obj_load_order_prio(struct obj_section *a) | |||
2105 | af = a->header.sh_flags; | 2106 | af = a->header.sh_flags; |
2106 | 2107 | ||
2107 | ac = 0; | 2108 | ac = 0; |
2108 | if (a->name[0] != '.' || strlen(a->name) != 10 || | 2109 | if (a->name[0] != '.' || strlen(a->name) != 10 |
2109 | strcmp(a->name + 5, ".init")) | 2110 | || strcmp(a->name + 5, ".init") != 0 |
2111 | ) { | ||
2110 | ac |= 32; | 2112 | ac |= 32; |
2113 | } | ||
2111 | if (af & SHF_ALLOC) | 2114 | if (af & SHF_ALLOC) |
2112 | ac |= 16; | 2115 | ac |= 16; |
2113 | if (!(af & SHF_WRITE)) | 2116 | if (!(af & SHF_WRITE)) |
@@ -2738,18 +2741,19 @@ static int new_create_module_ksymtab(struct obj_file *f) | |||
2738 | /* We don't want to export symbols residing in sections that | 2741 | /* We don't want to export symbols residing in sections that |
2739 | aren't loaded. There are a number of these created so that | 2742 | aren't loaded. There are a number of these created so that |
2740 | we make sure certain module options don't appear twice. */ | 2743 | we make sure certain module options don't appear twice. */ |
2741 | 2744 | i = f->header.e_shnum; | |
2742 | loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); | 2745 | loaded = alloca(sizeof(int) * i); |
2743 | while (--i >= 0) | 2746 | while (--i >= 0) |
2744 | loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; | 2747 | loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; |
2745 | 2748 | ||
2746 | for (nsyms = i = 0; i < HASH_BUCKETS; ++i) { | 2749 | for (nsyms = i = 0; i < HASH_BUCKETS; ++i) { |
2747 | struct obj_symbol *sym; | 2750 | struct obj_symbol *sym; |
2748 | for (sym = f->symtab[i]; sym; sym = sym->next) | 2751 | for (sym = f->symtab[i]; sym; sym = sym->next) { |
2749 | if (ELF_ST_BIND(sym->info) != STB_LOCAL | 2752 | if (ELF_ST_BIND(sym->info) != STB_LOCAL |
2750 | && sym->secidx <= SHN_HIRESERVE | 2753 | && sym->secidx <= SHN_HIRESERVE |
2751 | && (sym->secidx >= SHN_LORESERVE | 2754 | && (sym->secidx >= SHN_LORESERVE |
2752 | || loaded[sym->secidx])) { | 2755 | || loaded[sym->secidx]) |
2756 | ) { | ||
2753 | ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p; | 2757 | ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p; |
2754 | 2758 | ||
2755 | obj_symbol_patch(f, sec->idx, ofs, sym); | 2759 | obj_symbol_patch(f, sec->idx, ofs, sym); |
@@ -2758,6 +2762,7 @@ static int new_create_module_ksymtab(struct obj_file *f) | |||
2758 | 2762 | ||
2759 | nsyms++; | 2763 | nsyms++; |
2760 | } | 2764 | } |
2765 | } | ||
2761 | } | 2766 | } |
2762 | 2767 | ||
2763 | obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p); | 2768 | obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p); |
@@ -2816,9 +2821,11 @@ new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size) | |||
2816 | } | 2821 | } |
2817 | sec = obj_find_section(f, ".data.init"); | 2822 | sec = obj_find_section(f, ".data.init"); |
2818 | if (sec) { | 2823 | if (sec) { |
2819 | if (!module->runsize || | 2824 | if (!module->runsize |
2820 | module->runsize > sec->header.sh_addr - m_addr) | 2825 | || module->runsize > sec->header.sh_addr - m_addr |
2826 | ) { | ||
2821 | module->runsize = sec->header.sh_addr - m_addr; | 2827 | module->runsize = sec->header.sh_addr - m_addr; |
2828 | } | ||
2822 | } | 2829 | } |
2823 | sec = obj_find_section(f, ARCHDATA_SEC_NAME); | 2830 | sec = obj_find_section(f, ARCHDATA_SEC_NAME); |
2824 | if (sec && sec->header.sh_size) { | 2831 | if (sec && sec->header.sh_size) { |
@@ -3104,8 +3111,8 @@ static int obj_relocate(struct obj_file *f, ElfW(Addr) base) | |||
3104 | #if SHT_RELM == SHT_RELA | 3111 | #if SHT_RELM == SHT_RELA |
3105 | #if defined(__alpha__) && defined(AXP_BROKEN_GAS) | 3112 | #if defined(__alpha__) && defined(AXP_BROKEN_GAS) |
3106 | /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ | 3113 | /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ |
3107 | if (!extsym || !extsym->st_name || | 3114 | if (!extsym || !extsym->st_name |
3108 | ELF_ST_BIND(extsym->st_info) != STB_LOCAL) | 3115 | || ELF_ST_BIND(extsym->st_info) != STB_LOCAL) |
3109 | #endif | 3116 | #endif |
3110 | value += rel->r_addend; | 3117 | value += rel->r_addend; |
3111 | #endif | 3118 | #endif |
@@ -3211,16 +3218,17 @@ static struct obj_file *obj_load(FILE *fp, int loadprogbits UNUSED_PARAM) | |||
3211 | } | 3218 | } |
3212 | 3219 | ||
3213 | if (f->header.e_ident[EI_MAG0] != ELFMAG0 | 3220 | if (f->header.e_ident[EI_MAG0] != ELFMAG0 |
3214 | || f->header.e_ident[EI_MAG1] != ELFMAG1 | 3221 | || f->header.e_ident[EI_MAG1] != ELFMAG1 |
3215 | || f->header.e_ident[EI_MAG2] != ELFMAG2 | 3222 | || f->header.e_ident[EI_MAG2] != ELFMAG2 |
3216 | || f->header.e_ident[EI_MAG3] != ELFMAG3) { | 3223 | || f->header.e_ident[EI_MAG3] != ELFMAG3 |
3224 | ) { | ||
3217 | bb_error_msg_and_die("not an ELF file"); | 3225 | bb_error_msg_and_die("not an ELF file"); |
3218 | } | 3226 | } |
3219 | if (f->header.e_ident[EI_CLASS] != ELFCLASSM | 3227 | if (f->header.e_ident[EI_CLASS] != ELFCLASSM |
3220 | || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN | 3228 | || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB) |
3221 | ? ELFDATA2MSB : ELFDATA2LSB) | 3229 | || f->header.e_ident[EI_VERSION] != EV_CURRENT |
3222 | || f->header.e_ident[EI_VERSION] != EV_CURRENT | 3230 | || !MATCH_MACHINE(f->header.e_machine) |
3223 | || !MATCH_MACHINE(f->header.e_machine)) { | 3231 | ) { |
3224 | bb_error_msg_and_die("ELF file not for this architecture"); | 3232 | bb_error_msg_and_die("ELF file not for this architecture"); |
3225 | } | 3233 | } |
3226 | if (f->header.e_type != ET_REL) { | 3234 | if (f->header.e_type != ET_REL) { |
@@ -3236,8 +3244,10 @@ static struct obj_file *obj_load(FILE *fp, int loadprogbits UNUSED_PARAM) | |||
3236 | } | 3244 | } |
3237 | 3245 | ||
3238 | shnum = f->header.e_shnum; | 3246 | shnum = f->header.e_shnum; |
3239 | f->sections = xmalloc(sizeof(struct obj_section *) * shnum); | 3247 | /* Growth of ->sections vector will be done by |
3240 | memset(f->sections, 0, sizeof(struct obj_section *) * shnum); | 3248 | * xrealloc_vector(..., 2, ...), therefore we must allocate |
3249 | * at least 2^2 = 4 extra elements here. */ | ||
3250 | f->sections = xzalloc(sizeof(f->sections[0]) * (shnum + 4)); | ||
3241 | 3251 | ||
3242 | section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); | 3252 | section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); |
3243 | fseek(fp, f->header.e_shoff, SEEK_SET); | 3253 | fseek(fp, f->header.e_shoff, SEEK_SET); |
@@ -3742,16 +3752,20 @@ static void print_load_map(struct obj_file *f) | |||
3742 | for (nsyms = i = 0; i < HASH_BUCKETS; ++i) | 3752 | for (nsyms = i = 0; i < HASH_BUCKETS; ++i) |
3743 | for (sym = f->symtab[i]; sym; sym = sym->next) | 3753 | for (sym = f->symtab[i]; sym; sym = sym->next) |
3744 | if (sym->secidx <= SHN_HIRESERVE | 3754 | if (sym->secidx <= SHN_HIRESERVE |
3745 | && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])) | 3755 | && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]) |
3756 | ) { | ||
3746 | ++nsyms; | 3757 | ++nsyms; |
3758 | } | ||
3747 | 3759 | ||
3748 | all = alloca(nsyms * sizeof(struct obj_symbol *)); | 3760 | all = alloca(nsyms * sizeof(struct obj_symbol *)); |
3749 | 3761 | ||
3750 | for (i = 0, p = all; i < HASH_BUCKETS; ++i) | 3762 | for (i = 0, p = all; i < HASH_BUCKETS; ++i) |
3751 | for (sym = f->symtab[i]; sym; sym = sym->next) | 3763 | for (sym = f->symtab[i]; sym; sym = sym->next) |
3752 | if (sym->secidx <= SHN_HIRESERVE | 3764 | if (sym->secidx <= SHN_HIRESERVE |
3753 | && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])) | 3765 | && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx]) |
3766 | ) { | ||
3754 | *p++ = sym; | 3767 | *p++ = sym; |
3768 | } | ||
3755 | 3769 | ||
3756 | /* And list them. */ | 3770 | /* And list them. */ |
3757 | printf("\nSymbols:\n"); | 3771 | printf("\nSymbols:\n"); |