Merge branch 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6
* 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6: [PATCH] x86-64: Revert timer routing behaviour back to 2.6.16 state [PATCH] x86-64: Overlapping program headers in physical addr space fix [PATCH] x86-64: Put more than one cpu in TARGET_CPUS [PATCH] x86: Revert new unwind kernel stack termination [PATCH] x86-64: Use irq_domain in ioapic_retrigger_irq [PATCH] i386: Disable nmi watchdog on all ThinkPads [PATCH] x86-64: Revert interrupt backlink changes [PATCH] x86-64: Fix ENOSYS in system call tracing [PATCH] i386: Fix fake return address [PATCH] x86-64: x86_64 add NX mask for PTE entry [PATCH] x86-64: Speed up dwarf2 unwinder [PATCH] x86: Use -maccumulate-outgoing-args [PATCH] x86-64: fix page align in e820 allocator [PATCH] x86-64: Fix for arch/x86_64/pci/Makefile CFLAGS [PATCH] i386: fix .cfi_signal_frame copy-n-paste error [PATCH] x86-64: typo in __assign_irq_vector when updating pos for vector and offset [PATCH] x86-64: x86_64 hot-add memory srat.c fix [PATCH] i386: Update defconfig [PATCH] x86-64: Update defconfig
This commit is contained in:
commit
5d6aaf3f6d
24 changed files with 399 additions and 111 deletions
1
Makefile
1
Makefile
|
@ -499,6 +499,7 @@ endif
|
|||
|
||||
ifdef CONFIG_UNWIND_INFO
|
||||
CFLAGS += -fasynchronous-unwind-tables
|
||||
LDFLAGS_vmlinux += --eh-frame-hdr
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DEBUG_INFO
|
||||
|
|
|
@ -42,6 +42,10 @@ cflags-$(CONFIG_REGPARM) += -mregparm=3
|
|||
# temporary until string.h is fixed
|
||||
cflags-y += -ffreestanding
|
||||
|
||||
# this works around some issues with generating unwind tables in older gccs
|
||||
# newer gccs do it by default
|
||||
cflags-y += -maccumulate-outgoing-args
|
||||
|
||||
# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
|
||||
# a lot more stack due to the lack of sharing of stacklots:
|
||||
CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
|
||||
|
@ -51,8 +55,8 @@ cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
|||
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
||||
|
||||
# is .cfi_signal_frame supported too?
|
||||
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
||||
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
||||
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
|
||||
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
|
||||
|
||||
CFLAGS += $(cflags-y)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.19-rc1
|
||||
# Thu Oct 5 13:04:53 2006
|
||||
# Linux kernel version: 2.6.19-rc2-git4
|
||||
# Sat Oct 21 03:38:56 2006
|
||||
#
|
||||
CONFIG_X86_32=y
|
||||
CONFIG_GENERIC_TIME=y
|
||||
|
@ -380,8 +380,8 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=y
|
|||
CONFIG_INET6_XFRM_MODE_TUNNEL=y
|
||||
# CONFIG_INET6_XFRM_MODE_BEET is not set
|
||||
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
|
||||
CONFIG_IPV6_SIT=y
|
||||
# CONFIG_IPV6_TUNNEL is not set
|
||||
# CONFIG_IPV6_SUBTREES is not set
|
||||
# CONFIG_IPV6_MULTIPLE_TABLES is not set
|
||||
# CONFIG_NETWORK_SECMARK is not set
|
||||
# CONFIG_NETFILTER is not set
|
||||
|
@ -482,6 +482,13 @@ CONFIG_BLK_DEV_INITRD=y
|
|||
# CONFIG_CDROM_PKTCDVD is not set
|
||||
# CONFIG_ATA_OVER_ETH is not set
|
||||
|
||||
#
|
||||
# Misc devices
|
||||
#
|
||||
# CONFIG_IBM_ASM is not set
|
||||
# CONFIG_SGI_IOC4 is not set
|
||||
# CONFIG_TIFM_CORE is not set
|
||||
|
||||
#
|
||||
# ATA/ATAPI/MFM/RLL support
|
||||
#
|
||||
|
@ -1024,6 +1031,7 @@ CONFIG_HANGCHECK_TIMER=y
|
|||
#
|
||||
# Dallas's 1-wire bus
|
||||
#
|
||||
# CONFIG_W1 is not set
|
||||
|
||||
#
|
||||
# Hardware Monitoring support
|
||||
|
@ -1031,12 +1039,6 @@ CONFIG_HANGCHECK_TIMER=y
|
|||
# CONFIG_HWMON is not set
|
||||
# CONFIG_HWMON_VID is not set
|
||||
|
||||
#
|
||||
# Misc devices
|
||||
#
|
||||
# CONFIG_IBM_ASM is not set
|
||||
# CONFIG_TIFM_CORE is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
|
@ -1169,7 +1171,6 @@ CONFIG_USB_HIDINPUT=y
|
|||
# CONFIG_USB_ATI_REMOTE2 is not set
|
||||
# CONFIG_USB_KEYSPAN_REMOTE is not set
|
||||
# CONFIG_USB_APPLETOUCH is not set
|
||||
# CONFIG_USB_TRANCEVIBRATOR is not set
|
||||
|
||||
#
|
||||
# USB Imaging devices
|
||||
|
@ -1215,6 +1216,7 @@ CONFIG_USB_MON=y
|
|||
# CONFIG_USB_APPLEDISPLAY is not set
|
||||
# CONFIG_USB_SISUSBVGA is not set
|
||||
# CONFIG_USB_LD is not set
|
||||
# CONFIG_USB_TRANCEVIBRATOR is not set
|
||||
# CONFIG_USB_TEST is not set
|
||||
|
||||
#
|
||||
|
@ -1284,6 +1286,7 @@ CONFIG_EXT3_FS=y
|
|||
CONFIG_EXT3_FS_XATTR=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
# CONFIG_EXT3_FS_SECURITY is not set
|
||||
# CONFIG_EXT4DEV_FS is not set
|
||||
CONFIG_JBD=y
|
||||
# CONFIG_JBD_DEBUG is not set
|
||||
CONFIG_FS_MBCACHE=y
|
||||
|
@ -1307,6 +1310,7 @@ CONFIG_DNOTIFY=y
|
|||
# CONFIG_AUTOFS_FS is not set
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
# CONFIG_FUSE_FS is not set
|
||||
CONFIG_GENERIC_ACL=y
|
||||
|
||||
#
|
||||
# CD-ROM/DVD Filesystems
|
||||
|
@ -1384,7 +1388,6 @@ CONFIG_SUNRPC=y
|
|||
# CONFIG_CODA_FS is not set
|
||||
# CONFIG_AFS_FS is not set
|
||||
# CONFIG_9P_FS is not set
|
||||
CONFIG_GENERIC_ACL=y
|
||||
|
||||
#
|
||||
# Partition Types
|
||||
|
@ -1436,10 +1439,6 @@ CONFIG_NLS_ISO8859_15=y
|
|||
# CONFIG_NLS_KOI8_U is not set
|
||||
CONFIG_NLS_UTF8=y
|
||||
|
||||
#
|
||||
# Distributed Lock Manager
|
||||
#
|
||||
|
||||
#
|
||||
# Instrumentation Support
|
||||
#
|
||||
|
@ -1480,6 +1479,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
|
|||
CONFIG_UNWIND_INFO=y
|
||||
CONFIG_STACK_UNWIND=y
|
||||
# CONFIG_FORCED_INLINING is not set
|
||||
# CONFIG_HEADERS_CHECK is not set
|
||||
# CONFIG_RCU_TORTURE_TEST is not set
|
||||
# CONFIG_LKDTM is not set
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
|
|
|
@ -317,7 +317,7 @@ is386: movl $2,%ecx # set MP
|
|||
movl %eax,%gs
|
||||
lldt %ax
|
||||
cld # gcc2 wants the direction flag cleared at all times
|
||||
pushl %eax # fake return address
|
||||
pushl $0 # fake return address for unwinder
|
||||
#ifdef CONFIG_SMP
|
||||
movb ready, %cl
|
||||
movb $1, ready
|
||||
|
|
|
@ -219,11 +219,11 @@ static int __init check_nmi_watchdog(void)
|
|||
int cpu;
|
||||
|
||||
/* Enable NMI watchdog for newer systems.
|
||||
Actually it should be safe for most systems before 2004 too except
|
||||
for some IBM systems that corrupt registers when NMI happens
|
||||
during SMM. Unfortunately we don't have more exact information
|
||||
on these and use this coarse check. */
|
||||
if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004)
|
||||
Probably safe on most older systems too, but let's be careful.
|
||||
IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM
|
||||
which hangs the system. Disable watchdog for all thinkpads */
|
||||
if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 &&
|
||||
!dmi_name_in_vendors("ThinkPad"))
|
||||
nmi_watchdog = NMI_LOCAL_APIC;
|
||||
|
||||
if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
|
||||
|
|
|
@ -336,7 +336,6 @@ extern void kernel_thread_helper(void);
|
|||
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
||||
{
|
||||
struct pt_regs regs;
|
||||
int err;
|
||||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
|
||||
|
@ -351,10 +350,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
|||
regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
|
||||
|
||||
/* Ok, create the new process.. */
|
||||
err = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
|
||||
if (err == 0) /* terminate kernel stack */
|
||||
task_pt_regs(current)->eip = 0;
|
||||
return err;
|
||||
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
|
||||
|
|
|
@ -54,6 +54,10 @@ endif
|
|||
cflags-y += $(call cc-option,-funit-at-a-time)
|
||||
# prevent gcc from generating any FP code by mistake
|
||||
cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
|
||||
# this works around some issues with generating unwind tables in older gccs
|
||||
# newer gccs do it by default
|
||||
cflags-y += -maccumulate-outgoing-args
|
||||
|
||||
# do binutils support CFI?
|
||||
cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
||||
AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# Automatically generated make config: don't edit
|
||||
# Linux kernel version: 2.6.19-rc1
|
||||
# Thu Oct 5 13:04:43 2006
|
||||
# Linux kernel version: 2.6.19-rc2-git4
|
||||
# Sat Oct 21 03:38:52 2006
|
||||
#
|
||||
CONFIG_X86_64=y
|
||||
CONFIG_64BIT=y
|
||||
|
@ -335,8 +335,8 @@ CONFIG_IPV6=y
|
|||
# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
|
||||
# CONFIG_INET6_XFRM_MODE_BEET is not set
|
||||
# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
|
||||
CONFIG_IPV6_SIT=y
|
||||
# CONFIG_IPV6_TUNNEL is not set
|
||||
# CONFIG_IPV6_SUBTREES is not set
|
||||
# CONFIG_IPV6_MULTIPLE_TABLES is not set
|
||||
# CONFIG_NETWORK_SECMARK is not set
|
||||
# CONFIG_NETFILTER is not set
|
||||
|
@ -437,6 +437,13 @@ CONFIG_BLK_DEV_INITRD=y
|
|||
# CONFIG_CDROM_PKTCDVD is not set
|
||||
# CONFIG_ATA_OVER_ETH is not set
|
||||
|
||||
#
|
||||
# Misc devices
|
||||
#
|
||||
# CONFIG_IBM_ASM is not set
|
||||
# CONFIG_SGI_IOC4 is not set
|
||||
# CONFIG_TIFM_CORE is not set
|
||||
|
||||
#
|
||||
# ATA/ATAPI/MFM/RLL support
|
||||
#
|
||||
|
@ -1008,6 +1015,7 @@ CONFIG_I2C_ISA=m
|
|||
#
|
||||
# Dallas's 1-wire bus
|
||||
#
|
||||
# CONFIG_W1 is not set
|
||||
|
||||
#
|
||||
# Hardware Monitoring support
|
||||
|
@ -1058,12 +1066,6 @@ CONFIG_SENSORS_SMSC47B397=m
|
|||
# CONFIG_SENSORS_HDAPS is not set
|
||||
# CONFIG_HWMON_DEBUG_CHIP is not set
|
||||
|
||||
#
|
||||
# Misc devices
|
||||
#
|
||||
# CONFIG_IBM_ASM is not set
|
||||
# CONFIG_TIFM_CORE is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
|
@ -1196,7 +1198,6 @@ CONFIG_USB_HIDINPUT=y
|
|||
# CONFIG_USB_ATI_REMOTE2 is not set
|
||||
# CONFIG_USB_KEYSPAN_REMOTE is not set
|
||||
# CONFIG_USB_APPLETOUCH is not set
|
||||
# CONFIG_USB_TRANCEVIBRATOR is not set
|
||||
|
||||
#
|
||||
# USB Imaging devices
|
||||
|
@ -1242,6 +1243,7 @@ CONFIG_USB_MON=y
|
|||
# CONFIG_USB_APPLEDISPLAY is not set
|
||||
# CONFIG_USB_SISUSBVGA is not set
|
||||
# CONFIG_USB_LD is not set
|
||||
# CONFIG_USB_TRANCEVIBRATOR is not set
|
||||
# CONFIG_USB_TEST is not set
|
||||
|
||||
#
|
||||
|
@ -1318,6 +1320,7 @@ CONFIG_EXT3_FS=y
|
|||
CONFIG_EXT3_FS_XATTR=y
|
||||
CONFIG_EXT3_FS_POSIX_ACL=y
|
||||
# CONFIG_EXT3_FS_SECURITY is not set
|
||||
# CONFIG_EXT4DEV_FS is not set
|
||||
CONFIG_JBD=y
|
||||
# CONFIG_JBD_DEBUG is not set
|
||||
CONFIG_FS_MBCACHE=y
|
||||
|
@ -1341,6 +1344,7 @@ CONFIG_DNOTIFY=y
|
|||
# CONFIG_AUTOFS_FS is not set
|
||||
CONFIG_AUTOFS4_FS=y
|
||||
# CONFIG_FUSE_FS is not set
|
||||
CONFIG_GENERIC_ACL=y
|
||||
|
||||
#
|
||||
# CD-ROM/DVD Filesystems
|
||||
|
@ -1418,7 +1422,6 @@ CONFIG_SUNRPC=y
|
|||
# CONFIG_CODA_FS is not set
|
||||
# CONFIG_AFS_FS is not set
|
||||
# CONFIG_9P_FS is not set
|
||||
CONFIG_GENERIC_ACL=y
|
||||
|
||||
#
|
||||
# Partition Types
|
||||
|
@ -1470,10 +1473,6 @@ CONFIG_NLS_ISO8859_15=y
|
|||
# CONFIG_NLS_KOI8_U is not set
|
||||
CONFIG_NLS_UTF8=y
|
||||
|
||||
#
|
||||
# Distributed Lock Manager
|
||||
#
|
||||
|
||||
#
|
||||
# Instrumentation Support
|
||||
#
|
||||
|
@ -1512,6 +1511,7 @@ CONFIG_DEBUG_FS=y
|
|||
CONFIG_UNWIND_INFO=y
|
||||
CONFIG_STACK_UNWIND=y
|
||||
# CONFIG_FORCED_INLINING is not set
|
||||
# CONFIG_HEADERS_CHECK is not set
|
||||
# CONFIG_RCU_TORTURE_TEST is not set
|
||||
# CONFIG_LKDTM is not set
|
||||
# CONFIG_DEBUG_RODATA is not set
|
||||
|
|
|
@ -54,13 +54,13 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
|
|||
|
||||
/* various gunk below that needed for SMP startup */
|
||||
if (addr < 0x8000) {
|
||||
*addrp = 0x8000;
|
||||
*addrp = PAGE_ALIGN(0x8000);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* direct mapping tables of the kernel */
|
||||
if (last >= table_start<<PAGE_SHIFT && addr < table_end<<PAGE_SHIFT) {
|
||||
*addrp = table_end << PAGE_SHIFT;
|
||||
*addrp = PAGE_ALIGN(table_end << PAGE_SHIFT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -68,18 +68,18 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
|
|||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
if (LOADER_TYPE && INITRD_START && last >= INITRD_START &&
|
||||
addr < INITRD_START+INITRD_SIZE) {
|
||||
*addrp = INITRD_START + INITRD_SIZE;
|
||||
*addrp = PAGE_ALIGN(INITRD_START + INITRD_SIZE);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
/* kernel code */
|
||||
if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) {
|
||||
*addrp = __pa_symbol(&_end);
|
||||
if (last >= __pa_symbol(&_text) && addr < __pa_symbol(&_end)) {
|
||||
*addrp = PAGE_ALIGN(__pa_symbol(&_end));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (last >= ebda_addr && addr < ebda_addr + ebda_size) {
|
||||
*addrp = ebda_addr + ebda_size;
|
||||
*addrp = PAGE_ALIGN(ebda_addr + ebda_size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsi
|
|||
continue;
|
||||
while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size)
|
||||
;
|
||||
last = addr + size;
|
||||
last = PAGE_ALIGN(addr) + size;
|
||||
if (last > ei->addr + ei->size)
|
||||
continue;
|
||||
if (last > end)
|
||||
|
|
|
@ -61,10 +61,11 @@ static void nvidia_bugs(void)
|
|||
|
||||
static void ati_bugs(void)
|
||||
{
|
||||
#if 1 /* for testing */
|
||||
printk("ATI board detected\n");
|
||||
#endif
|
||||
/* No bugs right now */
|
||||
if (timer_over_8254 == 1) {
|
||||
timer_over_8254 = 0;
|
||||
printk(KERN_INFO
|
||||
"ATI board detected. Disabling timer routing over 8254.\n");
|
||||
}
|
||||
}
|
||||
|
||||
struct chipset {
|
||||
|
|
|
@ -315,6 +315,8 @@ tracesys:
|
|||
LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */
|
||||
RESTORE_REST
|
||||
cmpq $__NR_syscall_max,%rax
|
||||
movq $-ENOSYS,%rcx
|
||||
cmova %rcx,%rax
|
||||
ja 1f
|
||||
movq %r10,%rcx /* fixup for C */
|
||||
call *sys_call_table(,%rax,8)
|
||||
|
@ -535,8 +537,6 @@ END(stub_rt_sigreturn)
|
|||
1: incl %gs:pda_irqcount
|
||||
cmoveq %gs:pda_irqstackptr,%rsp
|
||||
push %rbp # backlink for old unwinder
|
||||
CFI_ADJUST_CFA_OFFSET 8
|
||||
CFI_REL_OFFSET rbp,0
|
||||
/*
|
||||
* We entered an interrupt context - irqs are off:
|
||||
*/
|
||||
|
@ -980,11 +980,6 @@ ENTRY(kernel_thread)
|
|||
call do_fork
|
||||
movq %rax,RAX(%rsp)
|
||||
xorl %edi,%edi
|
||||
test %rax,%rax
|
||||
jnz 1f
|
||||
/* terminate stack in child */
|
||||
movq %rdi,RIP(%rsp)
|
||||
1:
|
||||
|
||||
/*
|
||||
* It isn't worth to check for reschedule here,
|
||||
|
@ -1176,7 +1171,6 @@ ENTRY(call_softirq)
|
|||
incl %gs:pda_irqcount
|
||||
cmove %gs:pda_irqstackptr,%rsp
|
||||
push %rbp # backlink for old unwinder
|
||||
CFI_ADJUST_CFA_OFFSET 8
|
||||
call __do_softirq
|
||||
leaveq
|
||||
CFI_DEF_CFA_REGISTER rsp
|
||||
|
|
|
@ -153,7 +153,7 @@ struct genapic apic_flat = {
|
|||
|
||||
static cpumask_t physflat_target_cpus(void)
|
||||
{
|
||||
return cpumask_of_cpu(0);
|
||||
return cpu_online_map;
|
||||
}
|
||||
|
||||
static cpumask_t physflat_vector_allocation_domain(int cpu)
|
||||
|
|
|
@ -57,7 +57,7 @@ static int no_timer_check;
|
|||
|
||||
static int disable_timer_pin_1 __initdata;
|
||||
|
||||
int timer_over_8254 __initdata = 0;
|
||||
int timer_over_8254 __initdata = 1;
|
||||
|
||||
/* Where if anywhere is the i8259 connect in external int mode */
|
||||
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
|
||||
|
@ -651,12 +651,12 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result)
|
|||
if (vector == IA32_SYSCALL_VECTOR)
|
||||
goto next;
|
||||
for_each_cpu_mask(new_cpu, domain)
|
||||
if (per_cpu(vector_irq, cpu)[vector] != -1)
|
||||
if (per_cpu(vector_irq, new_cpu)[vector] != -1)
|
||||
goto next;
|
||||
/* Found one! */
|
||||
for_each_cpu_mask(new_cpu, domain) {
|
||||
pos[cpu].vector = vector;
|
||||
pos[cpu].offset = offset;
|
||||
pos[new_cpu].vector = vector;
|
||||
pos[new_cpu].offset = offset;
|
||||
}
|
||||
if (old_vector >= 0) {
|
||||
int old_cpu;
|
||||
|
@ -1255,12 +1255,15 @@ static int ioapic_retrigger_irq(unsigned int irq)
|
|||
{
|
||||
cpumask_t mask;
|
||||
unsigned vector;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&vector_lock, flags);
|
||||
vector = irq_vector[irq];
|
||||
cpus_clear(mask);
|
||||
cpu_set(vector >> 8, mask);
|
||||
cpu_set(first_cpu(irq_domain[irq]), mask);
|
||||
|
||||
send_IPI_mask(mask, vector & 0xff);
|
||||
send_IPI_mask(mask, vector);
|
||||
spin_unlock_irqrestore(&vector_lock, flags);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ PHDRS {
|
|||
text PT_LOAD FLAGS(5); /* R_E */
|
||||
data PT_LOAD FLAGS(7); /* RWE */
|
||||
user PT_LOAD FLAGS(7); /* RWE */
|
||||
data.init PT_LOAD FLAGS(7); /* RWE */
|
||||
note PT_NOTE FLAGS(4); /* R__ */
|
||||
}
|
||||
SECTIONS
|
||||
|
@ -131,7 +132,7 @@ SECTIONS
|
|||
. = ALIGN(8192); /* init_task */
|
||||
.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
|
||||
*(.data.init_task)
|
||||
} :data
|
||||
}:data.init
|
||||
|
||||
. = ALIGN(4096);
|
||||
.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
|
||||
|
|
|
@ -207,7 +207,7 @@ static inline int save_add_info(void)
|
|||
return hotadd_percent > 0;
|
||||
}
|
||||
#else
|
||||
int update_end_of_memory(unsigned long end) {return 0;}
|
||||
int update_end_of_memory(unsigned long end) {return -1;}
|
||||
static int hotadd_enough_memory(struct bootnode *nd) {return 1;}
|
||||
#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
|
||||
static inline int save_add_info(void) {return 1;}
|
||||
|
@ -337,7 +337,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
|
|||
push_node_boundaries(node, nd->start >> PAGE_SHIFT,
|
||||
nd->end >> PAGE_SHIFT);
|
||||
|
||||
if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) {
|
||||
if (ma->flags.hot_pluggable && (reserve_hotadd(node, start, end) < 0)) {
|
||||
/* Ignore hotadd region. Undo damage */
|
||||
printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
|
||||
*nd = oldnode;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# Reuse the i386 PCI subsystem
|
||||
#
|
||||
CFLAGS += -Iarch/i386/pci
|
||||
EXTRA_CFLAGS += -Iarch/i386/pci
|
||||
|
||||
obj-y := i386.o
|
||||
obj-$(CONFIG_PCI_DIRECT)+= direct.o
|
||||
|
|
|
@ -326,6 +326,26 @@ char *dmi_get_system_info(int field)
|
|||
}
|
||||
EXPORT_SYMBOL(dmi_get_system_info);
|
||||
|
||||
|
||||
/**
|
||||
* dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information.
|
||||
* @str: Case sensitive Name
|
||||
*/
|
||||
int dmi_name_in_vendors(char *str)
|
||||
{
|
||||
static int fields[] = { DMI_BIOS_VENDOR, DMI_BIOS_VERSION, DMI_SYS_VENDOR,
|
||||
DMI_PRODUCT_NAME, DMI_PRODUCT_VERSION, DMI_BOARD_VENDOR,
|
||||
DMI_BOARD_NAME, DMI_BOARD_VERSION, DMI_NONE };
|
||||
int i;
|
||||
for (i = 0; fields[i] != DMI_NONE; i++) {
|
||||
int f = fields[i];
|
||||
if (dmi_ident[f] && strstr(dmi_ident[f], str))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dmi_name_in_vendors);
|
||||
|
||||
/**
|
||||
* dmi_find_device - find onboard device by type/name
|
||||
* @type: device type or %DMI_DEV_TYPE_ANY to match all device types
|
||||
|
|
|
@ -125,6 +125,10 @@
|
|||
*(__param) \
|
||||
VMLINUX_SYMBOL(__stop___param) = .; \
|
||||
} \
|
||||
\
|
||||
/* Unwind data binary search table */ \
|
||||
EH_FRAME_HDR \
|
||||
\
|
||||
__end_rodata = .; \
|
||||
. = ALIGN(4096);
|
||||
|
||||
|
@ -157,6 +161,18 @@
|
|||
*(.kprobes.text) \
|
||||
VMLINUX_SYMBOL(__kprobes_text_end) = .;
|
||||
|
||||
#ifdef CONFIG_STACK_UNWIND
|
||||
/* Unwind data binary search table */
|
||||
#define EH_FRAME_HDR \
|
||||
.eh_frame_hdr : AT(ADDR(.eh_frame_hdr) - LOAD_OFFSET) { \
|
||||
VMLINUX_SYMBOL(__start_unwind_hdr) = .; \
|
||||
*(.eh_frame_hdr) \
|
||||
VMLINUX_SYMBOL(__end_unwind_hdr) = .; \
|
||||
}
|
||||
#else
|
||||
#define EH_FRAME_HDR
|
||||
#endif
|
||||
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to
|
||||
the beginning of the section so we begin them at 0. */
|
||||
|
|
|
@ -366,6 +366,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
|
|||
{
|
||||
pte_t pte;
|
||||
pte_val(pte) = physpage | pgprot_val(pgprot);
|
||||
pte_val(pte) &= __supported_pte_mask;
|
||||
return pte;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,6 +122,8 @@ extern int fix_aperture;
|
|||
extern int reboot_force;
|
||||
extern int notsc_setup(char *);
|
||||
|
||||
extern int timer_over_8254;
|
||||
|
||||
extern int gsi_irq_sharing(int gsi);
|
||||
|
||||
extern void smp_local_timer_interrupt(void);
|
||||
|
|
|
@ -69,6 +69,7 @@ extern struct dmi_device * dmi_find_device(int type, const char *name,
|
|||
struct dmi_device *from);
|
||||
extern void dmi_scan_machine(void);
|
||||
extern int dmi_get_year(int field);
|
||||
extern int dmi_name_in_vendors(char *str);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -77,6 +78,7 @@ static inline char * dmi_get_system_info(int field) { return NULL; }
|
|||
static inline struct dmi_device * dmi_find_device(int type, const char *name,
|
||||
struct dmi_device *from) { return NULL; }
|
||||
static inline int dmi_get_year(int year) { return 0; }
|
||||
static inline int dmi_name_in_vendors(char *s) { return 0; }
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ struct module;
|
|||
* Initialize unwind support.
|
||||
*/
|
||||
extern void unwind_init(void);
|
||||
extern void unwind_setup(void);
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
|
||||
|
@ -73,6 +74,7 @@ extern int unwind_to_user(struct unwind_frame_info *);
|
|||
struct unwind_frame_info {};
|
||||
|
||||
static inline void unwind_init(void) {}
|
||||
static inline void unwind_setup(void) {}
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
|
||||
|
|
|
@ -503,6 +503,7 @@ asmlinkage void __init start_kernel(void)
|
|||
printk(KERN_NOTICE);
|
||||
printk(linux_banner);
|
||||
setup_arch(&command_line);
|
||||
unwind_setup();
|
||||
setup_per_cpu_areas();
|
||||
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
|
||||
|
||||
|
|
316
kernel/unwind.c
316
kernel/unwind.c
|
@ -11,13 +11,15 @@
|
|||
|
||||
#include <linux/unwind.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/stop_machine.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
extern char __start_unwind[], __end_unwind[];
|
||||
extern const u8 __start_unwind_hdr[], __end_unwind_hdr[];
|
||||
|
||||
#define MAX_STACK_DEPTH 8
|
||||
|
||||
|
@ -100,6 +102,8 @@ static struct unwind_table {
|
|||
} core, init;
|
||||
const void *address;
|
||||
unsigned long size;
|
||||
const unsigned char *header;
|
||||
unsigned long hdrsz;
|
||||
struct unwind_table *link;
|
||||
const char *name;
|
||||
} root_table;
|
||||
|
@ -145,6 +149,10 @@ static struct unwind_table *find_table(unsigned long pc)
|
|||
return table;
|
||||
}
|
||||
|
||||
static unsigned long read_pointer(const u8 **pLoc,
|
||||
const void *end,
|
||||
signed ptrType);
|
||||
|
||||
static void init_unwind_table(struct unwind_table *table,
|
||||
const char *name,
|
||||
const void *core_start,
|
||||
|
@ -152,14 +160,30 @@ static void init_unwind_table(struct unwind_table *table,
|
|||
const void *init_start,
|
||||
unsigned long init_size,
|
||||
const void *table_start,
|
||||
unsigned long table_size)
|
||||
unsigned long table_size,
|
||||
const u8 *header_start,
|
||||
unsigned long header_size)
|
||||
{
|
||||
const u8 *ptr = header_start + 4;
|
||||
const u8 *end = header_start + header_size;
|
||||
|
||||
table->core.pc = (unsigned long)core_start;
|
||||
table->core.range = core_size;
|
||||
table->init.pc = (unsigned long)init_start;
|
||||
table->init.range = init_size;
|
||||
table->address = table_start;
|
||||
table->size = table_size;
|
||||
/* See if the linker provided table looks valid. */
|
||||
if (header_size <= 4
|
||||
|| header_start[0] != 1
|
||||
|| (void *)read_pointer(&ptr, end, header_start[1]) != table_start
|
||||
|| header_start[2] == DW_EH_PE_omit
|
||||
|| read_pointer(&ptr, end, header_start[2]) <= 0
|
||||
|| header_start[3] == DW_EH_PE_omit)
|
||||
header_start = NULL;
|
||||
table->hdrsz = header_size;
|
||||
smp_wmb();
|
||||
table->header = header_start;
|
||||
table->link = NULL;
|
||||
table->name = name;
|
||||
}
|
||||
|
@ -169,7 +193,143 @@ void __init unwind_init(void)
|
|||
init_unwind_table(&root_table, "kernel",
|
||||
_text, _end - _text,
|
||||
NULL, 0,
|
||||
__start_unwind, __end_unwind - __start_unwind);
|
||||
__start_unwind, __end_unwind - __start_unwind,
|
||||
__start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);
|
||||
}
|
||||
|
||||
static const u32 bad_cie, not_fde;
|
||||
static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
|
||||
static signed fde_pointer_type(const u32 *cie);
|
||||
|
||||
struct eh_frame_hdr_table_entry {
|
||||
unsigned long start, fde;
|
||||
};
|
||||
|
||||
static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
|
||||
{
|
||||
const struct eh_frame_hdr_table_entry *e1 = p1;
|
||||
const struct eh_frame_hdr_table_entry *e2 = p2;
|
||||
|
||||
return (e1->start > e2->start) - (e1->start < e2->start);
|
||||
}
|
||||
|
||||
static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
|
||||
{
|
||||
struct eh_frame_hdr_table_entry *e1 = p1;
|
||||
struct eh_frame_hdr_table_entry *e2 = p2;
|
||||
unsigned long v;
|
||||
|
||||
v = e1->start;
|
||||
e1->start = e2->start;
|
||||
e2->start = v;
|
||||
v = e1->fde;
|
||||
e1->fde = e2->fde;
|
||||
e2->fde = v;
|
||||
}
|
||||
|
||||
static void __init setup_unwind_table(struct unwind_table *table,
|
||||
void *(*alloc)(unsigned long))
|
||||
{
|
||||
const u8 *ptr;
|
||||
unsigned long tableSize = table->size, hdrSize;
|
||||
unsigned n;
|
||||
const u32 *fde;
|
||||
struct {
|
||||
u8 version;
|
||||
u8 eh_frame_ptr_enc;
|
||||
u8 fde_count_enc;
|
||||
u8 table_enc;
|
||||
unsigned long eh_frame_ptr;
|
||||
unsigned int fde_count;
|
||||
struct eh_frame_hdr_table_entry table[];
|
||||
} __attribute__((__packed__)) *header;
|
||||
|
||||
if (table->header)
|
||||
return;
|
||||
|
||||
if (table->hdrsz)
|
||||
printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n",
|
||||
table->name);
|
||||
|
||||
if (tableSize & (sizeof(*fde) - 1))
|
||||
return;
|
||||
|
||||
for (fde = table->address, n = 0;
|
||||
tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
|
||||
tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
|
||||
const u32 *cie = cie_for_fde(fde, table);
|
||||
signed ptrType;
|
||||
|
||||
if (cie == ¬_fde)
|
||||
continue;
|
||||
if (cie == NULL
|
||||
|| cie == &bad_cie
|
||||
|| (ptrType = fde_pointer_type(cie)) < 0)
|
||||
return;
|
||||
ptr = (const u8 *)(fde + 2);
|
||||
if (!read_pointer(&ptr,
|
||||
(const u8 *)(fde + 1) + *fde,
|
||||
ptrType))
|
||||
return;
|
||||
++n;
|
||||
}
|
||||
|
||||
if (tableSize || !n)
|
||||
return;
|
||||
|
||||
hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
|
||||
+ 2 * n * sizeof(unsigned long);
|
||||
header = alloc(hdrSize);
|
||||
if (!header)
|
||||
return;
|
||||
header->version = 1;
|
||||
header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native;
|
||||
header->fde_count_enc = DW_EH_PE_abs|DW_EH_PE_data4;
|
||||
header->table_enc = DW_EH_PE_abs|DW_EH_PE_native;
|
||||
put_unaligned((unsigned long)table->address, &header->eh_frame_ptr);
|
||||
BUILD_BUG_ON(offsetof(typeof(*header), fde_count)
|
||||
% __alignof(typeof(header->fde_count)));
|
||||
header->fde_count = n;
|
||||
|
||||
BUILD_BUG_ON(offsetof(typeof(*header), table)
|
||||
% __alignof(typeof(*header->table)));
|
||||
for (fde = table->address, tableSize = table->size, n = 0;
|
||||
tableSize;
|
||||
tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
|
||||
const u32 *cie = fde + 1 - fde[1] / sizeof(*fde);
|
||||
|
||||
if (!fde[1])
|
||||
continue; /* this is a CIE */
|
||||
ptr = (const u8 *)(fde + 2);
|
||||
header->table[n].start = read_pointer(&ptr,
|
||||
(const u8 *)(fde + 1) + *fde,
|
||||
fde_pointer_type(cie));
|
||||
header->table[n].fde = (unsigned long)fde;
|
||||
++n;
|
||||
}
|
||||
WARN_ON(n != header->fde_count);
|
||||
|
||||
sort(header->table,
|
||||
n,
|
||||
sizeof(*header->table),
|
||||
cmp_eh_frame_hdr_table_entries,
|
||||
swap_eh_frame_hdr_table_entries);
|
||||
|
||||
table->hdrsz = hdrSize;
|
||||
smp_wmb();
|
||||
table->header = (const void *)header;
|
||||
}
|
||||
|
||||
static void *__init balloc(unsigned long sz)
|
||||
{
|
||||
return __alloc_bootmem_nopanic(sz,
|
||||
sizeof(unsigned int),
|
||||
__pa(MAX_DMA_ADDRESS));
|
||||
}
|
||||
|
||||
void __init unwind_setup(void)
|
||||
{
|
||||
setup_unwind_table(&root_table, balloc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
|
@ -193,7 +353,8 @@ void *unwind_add_table(struct module *module,
|
|||
init_unwind_table(table, module->name,
|
||||
module->module_core, module->core_size,
|
||||
module->module_init, module->init_size,
|
||||
table_start, table_size);
|
||||
table_start, table_size,
|
||||
NULL, 0);
|
||||
|
||||
if (last_table)
|
||||
last_table->link = table;
|
||||
|
@ -303,6 +464,26 @@ static sleb128_t get_sleb128(const u8 **pcur, const u8 *end)
|
|||
return value;
|
||||
}
|
||||
|
||||
static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
|
||||
{
|
||||
const u32 *cie;
|
||||
|
||||
if (!*fde || (*fde & (sizeof(*fde) - 1)))
|
||||
return &bad_cie;
|
||||
if (!fde[1])
|
||||
return ¬_fde; /* this is a CIE */
|
||||
if ((fde[1] & (sizeof(*fde) - 1))
|
||||
|| fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address)
|
||||
return NULL; /* this is not a valid FDE */
|
||||
cie = fde + 1 - fde[1] / sizeof(*fde);
|
||||
if (*cie <= sizeof(*cie) + 4
|
||||
|| *cie >= fde[1] - sizeof(*fde)
|
||||
|| (*cie & (sizeof(*cie) - 1))
|
||||
|| cie[1])
|
||||
return NULL; /* this is not a (valid) CIE */
|
||||
return cie;
|
||||
}
|
||||
|
||||
static unsigned long read_pointer(const u8 **pLoc,
|
||||
const void *end,
|
||||
signed ptrType)
|
||||
|
@ -610,49 +791,108 @@ int unwind(struct unwind_frame_info *frame)
|
|||
unsigned i;
|
||||
signed ptrType = -1;
|
||||
uleb128_t retAddrReg = 0;
|
||||
struct unwind_table *table;
|
||||
const struct unwind_table *table;
|
||||
struct unwind_state state;
|
||||
|
||||
if (UNW_PC(frame) == 0)
|
||||
return -EINVAL;
|
||||
if ((table = find_table(pc)) != NULL
|
||||
&& !(table->size & (sizeof(*fde) - 1))) {
|
||||
unsigned long tableSize = table->size;
|
||||
const u8 *hdr = table->header;
|
||||
unsigned long tableSize;
|
||||
|
||||
for (fde = table->address;
|
||||
tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
|
||||
tableSize -= sizeof(*fde) + *fde,
|
||||
fde += 1 + *fde / sizeof(*fde)) {
|
||||
if (!*fde || (*fde & (sizeof(*fde) - 1)))
|
||||
break;
|
||||
if (!fde[1])
|
||||
continue; /* this is a CIE */
|
||||
if ((fde[1] & (sizeof(*fde) - 1))
|
||||
|| fde[1] > (unsigned long)(fde + 1)
|
||||
- (unsigned long)table->address)
|
||||
continue; /* this is not a valid FDE */
|
||||
cie = fde + 1 - fde[1] / sizeof(*fde);
|
||||
if (*cie <= sizeof(*cie) + 4
|
||||
|| *cie >= fde[1] - sizeof(*fde)
|
||||
|| (*cie & (sizeof(*cie) - 1))
|
||||
|| cie[1]
|
||||
|| (ptrType = fde_pointer_type(cie)) < 0) {
|
||||
cie = NULL; /* this is not a (valid) CIE */
|
||||
continue;
|
||||
smp_rmb();
|
||||
if (hdr && hdr[0] == 1) {
|
||||
switch(hdr[3] & DW_EH_PE_FORM) {
|
||||
case DW_EH_PE_native: tableSize = sizeof(unsigned long); break;
|
||||
case DW_EH_PE_data2: tableSize = 2; break;
|
||||
case DW_EH_PE_data4: tableSize = 4; break;
|
||||
case DW_EH_PE_data8: tableSize = 8; break;
|
||||
default: tableSize = 0; break;
|
||||
}
|
||||
ptr = hdr + 4;
|
||||
end = hdr + table->hdrsz;
|
||||
if (tableSize
|
||||
&& read_pointer(&ptr, end, hdr[1])
|
||||
== (unsigned long)table->address
|
||||
&& (i = read_pointer(&ptr, end, hdr[2])) > 0
|
||||
&& i == (end - ptr) / (2 * tableSize)
|
||||
&& !((end - ptr) % (2 * tableSize))) {
|
||||
do {
|
||||
const u8 *cur = ptr + (i / 2) * (2 * tableSize);
|
||||
|
||||
startLoc = read_pointer(&cur,
|
||||
cur + tableSize,
|
||||
hdr[3]);
|
||||
if (pc < startLoc)
|
||||
i /= 2;
|
||||
else {
|
||||
ptr = cur - tableSize;
|
||||
i = (i + 1) / 2;
|
||||
}
|
||||
} while (startLoc && i > 1);
|
||||
if (i == 1
|
||||
&& (startLoc = read_pointer(&ptr,
|
||||
ptr + tableSize,
|
||||
hdr[3])) != 0
|
||||
&& pc >= startLoc)
|
||||
fde = (void *)read_pointer(&ptr,
|
||||
ptr + tableSize,
|
||||
hdr[3]);
|
||||
}
|
||||
}
|
||||
|
||||
if (fde != NULL) {
|
||||
cie = cie_for_fde(fde, table);
|
||||
ptr = (const u8 *)(fde + 2);
|
||||
startLoc = read_pointer(&ptr,
|
||||
(const u8 *)(fde + 1) + *fde,
|
||||
ptrType);
|
||||
endLoc = startLoc
|
||||
+ read_pointer(&ptr,
|
||||
(const u8 *)(fde + 1) + *fde,
|
||||
ptrType & DW_EH_PE_indirect
|
||||
? ptrType
|
||||
: ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
|
||||
if (pc >= startLoc && pc < endLoc)
|
||||
break;
|
||||
cie = NULL;
|
||||
if(cie != NULL
|
||||
&& cie != &bad_cie
|
||||
&& cie != ¬_fde
|
||||
&& (ptrType = fde_pointer_type(cie)) >= 0
|
||||
&& read_pointer(&ptr,
|
||||
(const u8 *)(fde + 1) + *fde,
|
||||
ptrType) == startLoc) {
|
||||
if (!(ptrType & DW_EH_PE_indirect))
|
||||
ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
|
||||
endLoc = startLoc
|
||||
+ read_pointer(&ptr,
|
||||
(const u8 *)(fde + 1) + *fde,
|
||||
ptrType);
|
||||
if(pc >= endLoc)
|
||||
fde = NULL;
|
||||
} else
|
||||
fde = NULL;
|
||||
}
|
||||
if (fde == NULL) {
|
||||
for (fde = table->address, tableSize = table->size;
|
||||
cie = NULL, tableSize > sizeof(*fde)
|
||||
&& tableSize - sizeof(*fde) >= *fde;
|
||||
tableSize -= sizeof(*fde) + *fde,
|
||||
fde += 1 + *fde / sizeof(*fde)) {
|
||||
cie = cie_for_fde(fde, table);
|
||||
if (cie == &bad_cie) {
|
||||
cie = NULL;
|
||||
break;
|
||||
}
|
||||
if (cie == NULL
|
||||
|| cie == ¬_fde
|
||||
|| (ptrType = fde_pointer_type(cie)) < 0)
|
||||
continue;
|
||||
ptr = (const u8 *)(fde + 2);
|
||||
startLoc = read_pointer(&ptr,
|
||||
(const u8 *)(fde + 1) + *fde,
|
||||
ptrType);
|
||||
if (!startLoc)
|
||||
continue;
|
||||
if (!(ptrType & DW_EH_PE_indirect))
|
||||
ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
|
||||
endLoc = startLoc
|
||||
+ read_pointer(&ptr,
|
||||
(const u8 *)(fde + 1) + *fde,
|
||||
ptrType);
|
||||
if (pc >= startLoc && pc < endLoc)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cie != NULL) {
|
||||
|
|
Loading…
Reference in a new issue