summaryrefslogtreecommitdiff
path: root/modutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-09-28 16:40:25 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-09-28 16:40:25 +0000
commitbacaff6e5474d6c5f080ce4cd2a55e8ff1ba5c94 (patch)
tree5ca8c92753ef2c2fb7d39f125dc90deb18cfc1b8 /modutils
parent261cf4784fa39fb6cb3b7db99e809a7832d94d0a (diff)
downloadbusybox-w32-1_12_1.tar.gz
busybox-w32-1_12_1.tar.bz2
busybox-w32-1_12_1.zip
apply post-1.12.0 fixes, bump version to 1.12.11_12_1
Diffstat (limited to 'modutils')
-rw-r--r--modutils/insmod.c120
1 files changed, 65 insertions, 55 deletions
diff --git a/modutils/insmod.c b/modutils/insmod.c
index 9dcc5b02d..80dbfd78e 100644
--- a/modutils/insmod.c
+++ b/modutils/insmod.c
@@ -1059,8 +1059,9 @@ arch_apply_relocation(struct obj_file *f,
1059 1059
1060 case R_68K_PC8: 1060 case R_68K_PC8:
1061 v -= dot; 1061 v -= dot;
1062 if ((ElfW(Sword))v > 0x7f || 1062 if ((ElfW(Sword))v > 0x7f
1063 (ElfW(Sword))v < -(ElfW(Sword))0x80) { 1063 || (ElfW(Sword))v < -(ElfW(Sword))0x80
1064 ) {
1064 ret = obj_reloc_overflow; 1065 ret = obj_reloc_overflow;
1065 } 1066 }
1066 *(char *)loc = v; 1067 *(char *)loc = v;
@@ -1068,8 +1069,9 @@ arch_apply_relocation(struct obj_file *f,
1068 1069
1069 case R_68K_PC16: 1070 case R_68K_PC16:
1070 v -= dot; 1071 v -= dot;
1071 if ((ElfW(Sword))v > 0x7fff || 1072 if ((ElfW(Sword))v > 0x7fff
1072 (ElfW(Sword))v < -(ElfW(Sword))0x8000) { 1073 || (ElfW(Sword))v < -(ElfW(Sword))0x8000
1074 ) {
1073 ret = obj_reloc_overflow; 1075 ret = obj_reloc_overflow;
1074 } 1076 }
1075 *(short *)loc = v; 1077 *(short *)loc = v;
@@ -1208,8 +1210,9 @@ arch_apply_relocation(struct obj_file *f,
1208 { 1210 {
1209 Elf32_Addr word; 1211 Elf32_Addr word;
1210 1212
1211 if ((Elf32_Sword)v > 0x7fff || 1213 if ((Elf32_Sword)v > 0x7fff
1212 (Elf32_Sword)v < -(Elf32_Sword)0x8000) { 1214 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1215 ) {
1213 ret = obj_reloc_overflow; 1216 ret = obj_reloc_overflow;
1214 } 1217 }
1215 1218
@@ -1238,8 +1241,9 @@ arch_apply_relocation(struct obj_file *f,
1238 Elf32_Addr word; 1241 Elf32_Addr word;
1239 1242
1240 v -= dot + 4; 1243 v -= dot + 4;
1241 if ((Elf32_Sword)v > 0x7fff || 1244 if ((Elf32_Sword)v > 0x7fff
1242 (Elf32_Sword)v < -(Elf32_Sword)0x8000) { 1245 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1246 ) {
1243 ret = obj_reloc_overflow; 1247 ret = obj_reloc_overflow;
1244 } 1248 }
1245 1249
@@ -1253,9 +1257,10 @@ arch_apply_relocation(struct obj_file *f,
1253 Elf32_Addr word, gp; 1257 Elf32_Addr word, gp;
1254 /* get _gp */ 1258 /* get _gp */
1255 gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp")); 1259 gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp"));
1256 v-=gp; 1260 v -= gp;
1257 if ((Elf32_Sword)v > 0x7fff || 1261 if ((Elf32_Sword)v > 0x7fff
1258 (Elf32_Sword)v < -(Elf32_Sword)0x8000) { 1262 || (Elf32_Sword)v < -(Elf32_Sword)0x8000
1263 ) {
1259 ret = obj_reloc_overflow; 1264 ret = obj_reloc_overflow;
1260 } 1265 }
1261 1266
@@ -2132,7 +2137,6 @@ obj_find_symbol(struct obj_file *f, const char *name)
2132 for (sym = f->symtab[hash]; sym; sym = sym->next) 2137 for (sym = f->symtab[hash]; sym; sym = sym->next)
2133 if (f->symbol_cmp(sym->name, name) == 0) 2138 if (f->symbol_cmp(sym->name, name) == 0)
2134 return sym; 2139 return sym;
2135
2136 return NULL; 2140 return NULL;
2137} 2141}
2138 2142
@@ -2141,12 +2145,10 @@ static ElfW(Addr) obj_symbol_final_value(struct obj_file * f, struct obj_symbol
2141 if (sym) { 2145 if (sym) {
2142 if (sym->secidx >= SHN_LORESERVE) 2146 if (sym->secidx >= SHN_LORESERVE)
2143 return sym->value; 2147 return sym->value;
2144
2145 return sym->value + f->sections[sym->secidx]->header.sh_addr; 2148 return sym->value + f->sections[sym->secidx]->header.sh_addr;
2146 } else {
2147 /* As a special case, a NULL sym has value zero. */
2148 return 0;
2149 } 2149 }
2150 /* As a special case, a NULL sym has value zero. */
2151 return 0;
2150} 2152}
2151 2153
2152static struct obj_section *obj_find_section(struct obj_file *f, const char *name) 2154static struct obj_section *obj_find_section(struct obj_file *f, const char *name)
@@ -2156,7 +2158,6 @@ static struct obj_section *obj_find_section(struct obj_file *f, const char *name
2156 for (i = 0; i < n; ++i) 2158 for (i = 0; i < n; ++i)
2157 if (strcmp(f->sections[i]->name, name) == 0) 2159 if (strcmp(f->sections[i]->name, name) == 0)
2158 return f->sections[i]; 2160 return f->sections[i];
2159
2160 return NULL; 2161 return NULL;
2161} 2162}
2162 2163
@@ -2167,9 +2168,11 @@ static int obj_load_order_prio(struct obj_section *a)
2167 af = a->header.sh_flags; 2168 af = a->header.sh_flags;
2168 2169
2169 ac = 0; 2170 ac = 0;
2170 if (a->name[0] != '.' || strlen(a->name) != 10 || 2171 if (a->name[0] != '.' || strlen(a->name) != 10
2171 strcmp(a->name + 5, ".init")) 2172 || strcmp(a->name + 5, ".init") != 0
2173 ) {
2172 ac |= 32; 2174 ac |= 32;
2175 }
2173 if (af & SHF_ALLOC) 2176 if (af & SHF_ALLOC)
2174 ac |= 16; 2177 ac |= 16;
2175 if (!(af & SHF_WRITE)) 2178 if (!(af & SHF_WRITE))
@@ -2212,7 +2215,7 @@ static struct obj_section *obj_create_alloced_section(struct obj_file *f,
2212 sec->name = name; 2215 sec->name = name;
2213 sec->idx = newidx; 2216 sec->idx = newidx;
2214 if (size) 2217 if (size)
2215 sec->contents = xmalloc(size); 2218 sec->contents = xzalloc(size);
2216 2219
2217 obj_insert_section_load_order(f, sec); 2220 obj_insert_section_load_order(f, sec);
2218 2221
@@ -2227,7 +2230,7 @@ static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
2227 int newidx = f->header.e_shnum++; 2230 int newidx = f->header.e_shnum++;
2228 struct obj_section *sec; 2231 struct obj_section *sec;
2229 2232
2230 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); 2233 f->sections = xrealloc_vector(f->sections, 2, newidx);
2231 f->sections[newidx] = sec = arch_new_section(); 2234 f->sections[newidx] = sec = arch_new_section();
2232 2235
2233 sec->header.sh_type = SHT_PROGBITS; 2236 sec->header.sh_type = SHT_PROGBITS;
@@ -2237,7 +2240,7 @@ static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,
2237 sec->name = name; 2240 sec->name = name;
2238 sec->idx = newidx; 2241 sec->idx = newidx;
2239 if (size) 2242 if (size)
2240 sec->contents = xmalloc(size); 2243 sec->contents = xzalloc(size);
2241 2244
2242 sec->load_next = f->load_order; 2245 sec->load_next = f->load_order;
2243 f->load_order = sec; 2246 f->load_order = sec;
@@ -2689,8 +2692,7 @@ static void new_get_kernel_symbols(void)
2689 /* Collect the modules' symbols. */ 2692 /* Collect the modules' symbols. */
2690 2693
2691 if (nmod) { 2694 if (nmod) {
2692 ext_modules = modules = xmalloc(nmod * sizeof(*modules)); 2695 ext_modules = modules = xzalloc(nmod * sizeof(*modules));
2693 memset(modules, 0, nmod * sizeof(*modules));
2694 for (i = 0, mn = module_names, m = modules; 2696 for (i = 0, mn = module_names, m = modules;
2695 i < nmod; ++i, ++m, mn += strlen(mn) + 1) { 2697 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {
2696 struct new_module_info info; 2698 struct new_module_info info;
@@ -2770,13 +2772,14 @@ static int new_is_kernel_checksummed(void)
2770} 2772}
2771 2773
2772 2774
2773static void new_create_this_module(struct obj_file *f, const char *m_name) 2775static void new_create_this_module(struct obj_file *f, const char *m_name)
2774{ 2776{
2775 struct obj_section *sec; 2777 struct obj_section *sec;
2776 2778
2777 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long, 2779 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,
2778 sizeof(struct new_module)); 2780 sizeof(struct new_module));
2779 memset(sec->contents, 0, sizeof(struct new_module)); 2781 /* done by obj_create_alloced_section_first: */
2782 /*memset(sec->contents, 0, sizeof(struct new_module));*/
2780 2783
2781 obj_add_symbol(f, SPFX "__this_module", -1, 2784 obj_add_symbol(f, SPFX "__this_module", -1,
2782 ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0, 2785 ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0,
@@ -2856,18 +2859,19 @@ static int new_create_module_ksymtab(struct obj_file *f)
2856 /* We don't want to export symbols residing in sections that 2859 /* We don't want to export symbols residing in sections that
2857 aren't loaded. There are a number of these created so that 2860 aren't loaded. There are a number of these created so that
2858 we make sure certain module options don't appear twice. */ 2861 we make sure certain module options don't appear twice. */
2859 2862 i = f->header.e_shnum;
2860 loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); 2863 loaded = alloca(sizeof(int) * i);
2861 while (--i >= 0) 2864 while (--i >= 0)
2862 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; 2865 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;
2863 2866
2864 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) { 2867 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {
2865 struct obj_symbol *sym; 2868 struct obj_symbol *sym;
2866 for (sym = f->symtab[i]; sym; sym = sym->next) 2869 for (sym = f->symtab[i]; sym; sym = sym->next) {
2867 if (ELF_ST_BIND(sym->info) != STB_LOCAL 2870 if (ELF_ST_BIND(sym->info) != STB_LOCAL
2868 && sym->secidx <= SHN_HIRESERVE 2871 && sym->secidx <= SHN_HIRESERVE
2869 && (sym->secidx >= SHN_LORESERVE 2872 && (sym->secidx >= SHN_LORESERVE
2870 || loaded[sym->secidx])) { 2873 || loaded[sym->secidx])
2874 ) {
2871 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p; 2875 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;
2872 2876
2873 obj_symbol_patch(f, sec->idx, ofs, sym); 2877 obj_symbol_patch(f, sec->idx, ofs, sym);
@@ -2876,6 +2880,7 @@ static int new_create_module_ksymtab(struct obj_file *f)
2876 2880
2877 nsyms++; 2881 nsyms++;
2878 } 2882 }
2883 }
2879 } 2884 }
2880 2885
2881 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p); 2886 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);
@@ -2934,9 +2939,11 @@ new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size)
2934 } 2939 }
2935 sec = obj_find_section(f, ".data.init"); 2940 sec = obj_find_section(f, ".data.init");
2936 if (sec) { 2941 if (sec) {
2937 if (!module->runsize || 2942 if (!module->runsize
2938 module->runsize > sec->header.sh_addr - m_addr) 2943 || module->runsize > sec->header.sh_addr - m_addr
2944 ) {
2939 module->runsize = sec->header.sh_addr - m_addr; 2945 module->runsize = sec->header.sh_addr - m_addr;
2946 }
2940 } 2947 }
2941 sec = obj_find_section(f, ARCHDATA_SEC_NAME); 2948 sec = obj_find_section(f, ARCHDATA_SEC_NAME);
2942 if (sec && sec->header.sh_size) { 2949 if (sec && sec->header.sh_size) {
@@ -3083,9 +3090,9 @@ static void obj_allocate_commons(struct obj_file *f)
3083 if (i == f->header.e_shnum) { 3090 if (i == f->header.e_shnum) {
3084 struct obj_section *sec; 3091 struct obj_section *sec;
3085 3092
3093 f->header.e_shnum++;
3086 f->sections = xrealloc_vector(f->sections, 2, i); 3094 f->sections = xrealloc_vector(f->sections, 2, i);
3087 f->sections[i] = sec = arch_new_section(); 3095 f->sections[i] = sec = arch_new_section();
3088 f->header.e_shnum = i + 1;
3089 3096
3090 sec->header.sh_type = SHT_PROGBITS; 3097 sec->header.sh_type = SHT_PROGBITS;
3091 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; 3098 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;
@@ -3124,12 +3131,9 @@ static void obj_allocate_commons(struct obj_file *f)
3124 for (i = 0; i < f->header.e_shnum; ++i) { 3131 for (i = 0; i < f->header.e_shnum; ++i) {
3125 struct obj_section *s = f->sections[i]; 3132 struct obj_section *s = f->sections[i];
3126 if (s->header.sh_type == SHT_NOBITS) { 3133 if (s->header.sh_type == SHT_NOBITS) {
3134 s->contents = NULL;
3127 if (s->header.sh_size != 0) 3135 if (s->header.sh_size != 0)
3128 s->contents = memset(xmalloc(s->header.sh_size), 3136 s->contents = xzalloc(s->header.sh_size),
3129 0, s->header.sh_size);
3130 else
3131 s->contents = NULL;
3132
3133 s->header.sh_type = SHT_PROGBITS; 3137 s->header.sh_type = SHT_PROGBITS;
3134 } 3138 }
3135 } 3139 }
@@ -3222,8 +3226,8 @@ static int obj_relocate(struct obj_file *f, ElfW(Addr) base)
3222#if SHT_RELM == SHT_RELA 3226#if SHT_RELM == SHT_RELA
3223#if defined(__alpha__) && defined(AXP_BROKEN_GAS) 3227#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
3224 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ 3228 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
3225 if (!extsym || !extsym->st_name || 3229 if (!extsym || !extsym->st_name
3226 ELF_ST_BIND(extsym->st_info) != STB_LOCAL) 3230 || ELF_ST_BIND(extsym->st_info) != STB_LOCAL)
3227#endif 3231#endif
3228 value += rel->r_addend; 3232 value += rel->r_addend;
3229#endif 3233#endif
@@ -3329,16 +3333,17 @@ static struct obj_file *obj_load(FILE *fp, int loadprogbits UNUSED_PARAM)
3329 } 3333 }
3330 3334
3331 if (f->header.e_ident[EI_MAG0] != ELFMAG0 3335 if (f->header.e_ident[EI_MAG0] != ELFMAG0
3332 || f->header.e_ident[EI_MAG1] != ELFMAG1 3336 || f->header.e_ident[EI_MAG1] != ELFMAG1
3333 || f->header.e_ident[EI_MAG2] != ELFMAG2 3337 || f->header.e_ident[EI_MAG2] != ELFMAG2
3334 || f->header.e_ident[EI_MAG3] != ELFMAG3) { 3338 || f->header.e_ident[EI_MAG3] != ELFMAG3
3339 ) {
3335 bb_error_msg_and_die("not an ELF file"); 3340 bb_error_msg_and_die("not an ELF file");
3336 } 3341 }
3337 if (f->header.e_ident[EI_CLASS] != ELFCLASSM 3342 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
3338 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN 3343 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB)
3339 ? ELFDATA2MSB : ELFDATA2LSB) 3344 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3340 || f->header.e_ident[EI_VERSION] != EV_CURRENT 3345 || !MATCH_MACHINE(f->header.e_machine)
3341 || !MATCH_MACHINE(f->header.e_machine)) { 3346 ) {
3342 bb_error_msg_and_die("ELF file not for this architecture"); 3347 bb_error_msg_and_die("ELF file not for this architecture");
3343 } 3348 }
3344 if (f->header.e_type != ET_REL) { 3349 if (f->header.e_type != ET_REL) {
@@ -3354,8 +3359,10 @@ static struct obj_file *obj_load(FILE *fp, int loadprogbits UNUSED_PARAM)
3354 } 3359 }
3355 3360
3356 shnum = f->header.e_shnum; 3361 shnum = f->header.e_shnum;
3357 f->sections = xmalloc(sizeof(struct obj_section *) * shnum); 3362 /* Growth of ->sections vector will be done by
3358 memset(f->sections, 0, sizeof(struct obj_section *) * shnum); 3363 * xrealloc_vector(..., 2, ...), therefore we must allocate
3364 * at least 2^2 = 4 extra elements here. */
3365 f->sections = xzalloc(sizeof(f->sections[0]) * (shnum + 4));
3359 3366
3360 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); 3367 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
3361 fseek(fp, f->header.e_shoff, SEEK_SET); 3368 fseek(fp, f->header.e_shoff, SEEK_SET);
@@ -3391,14 +3398,13 @@ static struct obj_file *obj_load(FILE *fp, int loadprogbits UNUSED_PARAM)
3391 case SHT_SYMTAB: 3398 case SHT_SYMTAB:
3392 case SHT_STRTAB: 3399 case SHT_STRTAB:
3393 case SHT_RELM: 3400 case SHT_RELM:
3401 sec->contents = NULL;
3394 if (sec->header.sh_size > 0) { 3402 if (sec->header.sh_size > 0) {
3395 sec->contents = xmalloc(sec->header.sh_size); 3403 sec->contents = xzalloc(sec->header.sh_size);
3396 fseek(fp, sec->header.sh_offset, SEEK_SET); 3404 fseek(fp, sec->header.sh_offset, SEEK_SET);
3397 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { 3405 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) {
3398 bb_perror_msg_and_die("error reading ELF section data"); 3406 bb_perror_msg_and_die("error reading ELF section data");
3399 } 3407 }
3400 } else {
3401 sec->contents = NULL;
3402 } 3408 }
3403 break; 3409 break;
3404 3410
@@ -3860,16 +3866,20 @@ static void print_load_map(struct obj_file *f)
3860 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) 3866 for (nsyms = i = 0; i < HASH_BUCKETS; ++i)
3861 for (sym = f->symtab[i]; sym; sym = sym->next) 3867 for (sym = f->symtab[i]; sym; sym = sym->next)
3862 if (sym->secidx <= SHN_HIRESERVE 3868 if (sym->secidx <= SHN_HIRESERVE
3863 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])) 3869 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
3870 ) {
3864 ++nsyms; 3871 ++nsyms;
3872 }
3865 3873
3866 all = alloca(nsyms * sizeof(struct obj_symbol *)); 3874 all = alloca(nsyms * sizeof(struct obj_symbol *));
3867 3875
3868 for (i = 0, p = all; i < HASH_BUCKETS; ++i) 3876 for (i = 0, p = all; i < HASH_BUCKETS; ++i)
3869 for (sym = f->symtab[i]; sym; sym = sym->next) 3877 for (sym = f->symtab[i]; sym; sym = sym->next)
3870 if (sym->secidx <= SHN_HIRESERVE 3878 if (sym->secidx <= SHN_HIRESERVE
3871 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])) 3879 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])
3880 ) {
3872 *p++ = sym; 3881 *p++ = sym;
3882 }
3873 3883
3874 /* And list them. */ 3884 /* And list them. */
3875 printf("\nSymbols:\n"); 3885 printf("\nSymbols:\n");
@@ -4265,7 +4275,7 @@ static int insmod_ng_main(int argc UNUSED_PARAM, char **argv)
4265 } 4275 }
4266#else 4276#else
4267 len = MAXINT(ssize_t); 4277 len = MAXINT(ssize_t);
4268 map = xmalloc_open_read_close(filename, &len); 4278 map = xmalloc_xopen_read_close(filename, &len);
4269#endif 4279#endif
4270 4280
4271 if (init_module(map, len, options) != 0) 4281 if (init_module(map, len, options) != 0)