67 lines
1.8 KiB
C
67 lines
1.8 KiB
C
/* Copyright 2017 IBM Corp.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
* implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef __ELF_ABI_H
|
|
#define __ELF_ABI_H
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#if defined (_CALL_ELF) && _CALL_ELF == 2
|
|
#define ELF_ABI_v2
|
|
#else
|
|
#define ELF_ABI_v1
|
|
#endif
|
|
|
|
/* From linux/arch/powerpc/include/asm/code-patching.h */
|
|
#define OP_RT_RA_MASK 0xffff0000UL
|
|
#define LIS_R2 0x3c020000UL
|
|
#define ADDIS_R2_R12 0x3c4c0000UL
|
|
#define ADDI_R2_R2 0x38420000UL
|
|
|
|
static inline uint64_t function_entry_address(void *func)
|
|
{
|
|
#ifdef ELF_ABI_v2
|
|
u32 *insn = func;
|
|
/*
|
|
* A PPC64 ABIv2 function may have a local and a global entry
|
|
* point. We use the local entry point for branch tables called
|
|
* from asm, only a single TOC is used, so identify and step over
|
|
* the global entry point sequence.
|
|
*
|
|
* The global entry point sequence is always of the form:
|
|
*
|
|
* addis r2,r12,XXXX
|
|
* addi r2,r2,XXXX
|
|
*
|
|
* A linker optimisation may convert the addis to lis:
|
|
*
|
|
* lis r2,XXXX
|
|
* addi r2,r2,XXXX
|
|
*/
|
|
if ((((*insn & OP_RT_RA_MASK) == ADDIS_R2_R12) ||
|
|
((*insn & OP_RT_RA_MASK) == LIS_R2)) &&
|
|
((*(insn+1) & OP_RT_RA_MASK) == ADDI_R2_R2))
|
|
return (uint64_t)(insn + 2);
|
|
else
|
|
return (uint64_t)func;
|
|
#else
|
|
return *(uint64_t *)func;
|
|
#endif
|
|
}
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#endif /* __COMPILER_H */
|