aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2008-01-18 15:49:29 -0500
committerSam Ravnborg <sam@ravnborg.org>2008-01-28 17:14:40 -0500
commit5b24c0715fc4c71e60e9a684248cc49d62dfa900 (patch)
treed463896713b538ac9cf5ce637a9ee9d54d952055 /scripts
parent9ad21c3f3ecffeb56be7b35030d7ec2f30b6fe11 (diff)
kbuild: code refactoring in modpost
Split a too long function up in smaller bits to make prgram logic easier to follow. A few related changes done due to parameter changes. No functional changes. Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/mod/modpost.c242
1 files changed, 137 insertions, 105 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 902ee55f327f..e4630135979c 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -937,19 +937,19 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
937} 937}
938 938
939static unsigned int *reloc_location(struct elf_info *elf, 939static unsigned int *reloc_location(struct elf_info *elf,
940 int rsection, Elf_Rela *r) 940 Elf_Shdr *sechdr, Elf_Rela *r)
941{ 941{
942 Elf_Shdr *sechdrs = elf->sechdrs; 942 Elf_Shdr *sechdrs = elf->sechdrs;
943 int section = sechdrs[rsection].sh_info; 943 int section = sechdr->sh_info;
944 944
945 return (void *)elf->hdr + sechdrs[section].sh_offset + 945 return (void *)elf->hdr + sechdrs[section].sh_offset +
946 (r->r_offset - sechdrs[section].sh_addr); 946 (r->r_offset - sechdrs[section].sh_addr);
947} 947}
948 948
949static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r) 949static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
950{ 950{
951 unsigned int r_typ = ELF_R_TYPE(r->r_info); 951 unsigned int r_typ = ELF_R_TYPE(r->r_info);
952 unsigned int *location = reloc_location(elf, rsection, r); 952 unsigned int *location = reloc_location(elf, sechdr, r);
953 953
954 switch (r_typ) { 954 switch (r_typ) {
955 case R_386_32: 955 case R_386_32:
@@ -965,7 +965,7 @@ static int addend_386_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
965 return 0; 965 return 0;
966} 966}
967 967
968static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r) 968static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
969{ 969{
970 unsigned int r_typ = ELF_R_TYPE(r->r_info); 970 unsigned int r_typ = ELF_R_TYPE(r->r_info);
971 971
@@ -978,8 +978,8 @@ static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
978 case R_ARM_PC24: 978 case R_ARM_PC24:
979 /* From ARM ABI: ((S + A) | T) - P */ 979 /* From ARM ABI: ((S + A) | T) - P */
980 r->r_addend = (int)(long)(elf->hdr + 980 r->r_addend = (int)(long)(elf->hdr +
981 elf->sechdrs[rsection].sh_offset + 981 sechdr->sh_offset +
982 (r->r_offset - elf->sechdrs[rsection].sh_addr)); 982 (r->r_offset - sechdr->sh_addr));
983 break; 983 break;
984 default: 984 default:
985 return 1; 985 return 1;
@@ -987,10 +987,10 @@ static int addend_arm_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
987 return 0; 987 return 0;
988} 988}
989 989
990static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r) 990static int addend_mips_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
991{ 991{
992 unsigned int r_typ = ELF_R_TYPE(r->r_info); 992 unsigned int r_typ = ELF_R_TYPE(r->r_info);
993 unsigned int *location = reloc_location(elf, rsection, r); 993 unsigned int *location = reloc_location(elf, sechdr, r);
994 unsigned int inst; 994 unsigned int inst;
995 995
996 if (r_typ == R_MIPS_HI16) 996 if (r_typ == R_MIPS_HI16)
@@ -1010,6 +1010,128 @@ static int addend_mips_rel(struct elf_info *elf, int rsection, Elf_Rela *r)
1010 return 0; 1010 return 0;
1011} 1011}
1012 1012
1013static void section_rela(const char *modname, struct elf_info *elf,
1014 Elf_Shdr *sechdr, int section(const char *),
1015 int section_ref_ok(const char *))
1016{
1017 Elf_Sym *sym;
1018 Elf_Rela *rela;
1019 Elf_Rela r;
1020 unsigned int r_sym;
1021 const char *fromsec;
1022 const char * tosec;
1023
1024 Elf_Ehdr *hdr = elf->hdr;
1025 Elf_Rela *start = (void *)hdr + sechdr->sh_offset;
1026 Elf_Rela *stop = (void *)start + sechdr->sh_size;
1027
1028 const char *secstrings = (void *)hdr +
1029 elf->sechdrs[hdr->e_shstrndx].sh_offset;
1030
1031 fromsec = secstrings + sechdr->sh_name;
1032 fromsec += strlen(".rela");
1033 /* if from section (name) is know good then skip it */
1034 if (section_ref_ok(fromsec))
1035 return;
1036
1037 for (rela = start; rela < stop; rela++) {
1038 r.r_offset = TO_NATIVE(rela->r_offset);
1039#if KERNEL_ELFCLASS == ELFCLASS64
1040 if (hdr->e_machine == EM_MIPS) {
1041 unsigned int r_typ;
1042 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
1043 r_sym = TO_NATIVE(r_sym);
1044 r_typ = ELF64_MIPS_R_TYPE(rela->r_info);
1045 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1046 } else {
1047 r.r_info = TO_NATIVE(rela->r_info);
1048 r_sym = ELF_R_SYM(r.r_info);
1049 }
1050#else
1051 r.r_info = TO_NATIVE(rela->r_info);
1052 r_sym = ELF_R_SYM(r.r_info);
1053#endif
1054 r.r_addend = TO_NATIVE(rela->r_addend);
1055 sym = elf->symtab_start + r_sym;
1056 /* Skip special sections */
1057 if (sym->st_shndx >= SHN_LORESERVE)
1058 continue;
1059
1060 tosec = secstrings +
1061 elf->sechdrs[sym->st_shndx].sh_name;
1062 if (section(tosec))
1063 warn_sec_mismatch(modname, fromsec, elf, sym, r);
1064 }
1065}
1066
1067static void section_rel(const char *modname, struct elf_info *elf,
1068 Elf_Shdr *sechdr, int section(const char *),
1069 int section_ref_ok(const char *))
1070{
1071 Elf_Sym *sym;
1072 Elf_Rel *rel;
1073 Elf_Rela r;
1074 unsigned int r_sym;
1075 const char *fromsec;
1076 const char * tosec;
1077
1078 Elf_Ehdr *hdr = elf->hdr;
1079 Elf_Rel *start = (void *)hdr + sechdr->sh_offset;
1080 Elf_Rel *stop = (void *)start + sechdr->sh_size;
1081
1082 const char *secstrings = (void *)hdr +
1083 elf->sechdrs[hdr->e_shstrndx].sh_offset;
1084
1085 fromsec = secstrings + sechdr->sh_name;
1086 fromsec += strlen(".rel");
1087 /* if from section (name) is know good then skip it */
1088 if (section_ref_ok(fromsec))
1089 return;
1090
1091 for (rel = start; rel < stop; rel++) {
1092 r.r_offset = TO_NATIVE(rel->r_offset);
1093#if KERNEL_ELFCLASS == ELFCLASS64
1094 if (hdr->e_machine == EM_MIPS) {
1095 unsigned int r_typ;
1096 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
1097 r_sym = TO_NATIVE(r_sym);
1098 r_typ = ELF64_MIPS_R_TYPE(rel->r_info);
1099 r.r_info = ELF64_R_INFO(r_sym, r_typ);
1100 } else {
1101 r.r_info = TO_NATIVE(rel->r_info);
1102 r_sym = ELF_R_SYM(r.r_info);
1103 }
1104#else
1105 r.r_info = TO_NATIVE(rel->r_info);
1106 r_sym = ELF_R_SYM(r.r_info);
1107#endif
1108 r.r_addend = 0;
1109 switch (hdr->e_machine) {
1110 case EM_386:
1111 if (addend_386_rel(elf, sechdr, &r))
1112 continue;
1113 break;
1114 case EM_ARM:
1115 if (addend_arm_rel(elf, sechdr, &r))
1116 continue;
1117 break;
1118 case EM_MIPS:
1119 if (addend_mips_rel(elf, sechdr, &r))
1120 continue;
1121 break;
1122 }
1123 sym = elf->symtab_start + r_sym;
1124 /* Skip special sections */
1125 if (sym->st_shndx >= SHN_LORESERVE)
1126 continue;
1127
1128 tosec = secstrings +
1129 elf->sechdrs[sym->st_shndx].sh_name;
1130 if (sectio