kernel: fix 64-bit for kobject generation

We need a format code for struct packing that fits in
a pointer value, "I" is fixed at 32-bit.

The conversion of string to pointer value now prints
8 bytes. This works for 32-bit since the leading
4 digits are always zero.

The replaced length check uses sizeof(void *) and not 4.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2019-11-18 17:06:13 -08:00 committed by Andrew Boie
commit f290ab595c
3 changed files with 33 additions and 9 deletions

View file

@ -353,6 +353,19 @@ def analyze_typedef(die):
type_env[die.offset] = type_env[type_offset] type_env[die.offset] = type_env[type_offset]
def unpack_pointer(elf, data, offset):
endian_code = "<" if elf.little_endian else ">"
if elf.elfclass == 32:
size_code = "I"
size = 4
else:
size_code = "Q"
size = 8
return struct.unpack(endian_code + size_code,
data[offset:offset + size])[0]
def addr_deref(elf, addr): def addr_deref(elf, addr):
for section in elf.iter_sections(): for section in elf.iter_sections():
start = section['sh_addr'] start = section['sh_addr']
@ -361,14 +374,15 @@ def addr_deref(elf, addr):
if start <= addr < end: if start <= addr < end:
data = section.data() data = section.data()
offset = addr - start offset = addr - start
return struct.unpack("<I" if elf.little_endian else ">I", return unpack_pointer(elf, data, offset)
data[offset:offset + 4])[0]
return 0 return 0
def device_get_api_addr(elf, addr): def device_get_api_addr(elf, addr):
return addr_deref(elf, addr + 4) # Read device->driver API
offset = 4 if elf.elfclass == 32 else 8
return addr_deref(elf, addr + offset)
def get_filename_lineno(die): def get_filename_lineno(die):

View file

@ -200,7 +200,17 @@ def write_gperf_table(fp, eh, objs, static_begin, static_end):
initialized = static_begin <= obj_addr < static_end initialized = static_begin <= obj_addr < static_end
is_driver = obj_type.startswith("K_OBJ_DRIVER_") is_driver = obj_type.startswith("K_OBJ_DRIVER_")
byte_str = struct.pack("<I" if eh.little_endian else ">I", obj_addr) if "CONFIG_64BIT" in syms:
format_code = "Q"
else:
format_code = "I"
if eh.little_endian:
endian = "<"
else:
endian = ">"
byte_str = struct.pack(endian + format_code, obj_addr)
fp.write("\"") fp.write("\"")
for byte in byte_str: for byte in byte_str:
val = "\\x%02x" % byte val = "\\x%02x" % byte

View file

@ -49,8 +49,8 @@ def reformat_str(match_obj):
# Nip quotes # Nip quotes
addr_str = addr_str[1:-1] addr_str = addr_str[1:-1]
addr_vals = [0, 0, 0, 0] addr_vals = [0, 0, 0, 0, 0, 0, 0 , 0]
ctr = 3 ctr = 7
i = 0 i = 0
while True: while True:
@ -74,7 +74,7 @@ def reformat_str(match_obj):
ctr -= 1 ctr -= 1
return "(char *)0x%02x%02x%02x%02x" % tuple(addr_vals) return "(char *)0x%02x%02x%02x%02x%02x%02x%02x%02x" % tuple(addr_vals)
def process_line(line, fp): def process_line(line, fp):
@ -97,9 +97,9 @@ def process_line(line, fp):
warn("gperf %s is not tested, versions %s through %s supported" % warn("gperf %s is not tested, versions %s through %s supported" %
(v, v_lo, v_hi)) (v, v_lo, v_hi))
# Replace length lookups with constant len of 4 since we're always # Replace length lookups with constant len since we're always
# looking at pointers # looking at pointers
line = re.sub(r'lengthtable\[key\]', r'4', line) line = re.sub(r'lengthtable\[key\]', r'sizeof(void *)', line)
# Empty wordlist entries to have NULLs instead of "" # Empty wordlist entries to have NULLs instead of ""
line = re.sub(r'[{]["]["][}]', r'{}', line) line = re.sub(r'[{]["]["][}]', r'{}', line)