我试图将要构建的静态链接二进制文件的入口重新定位为固定值,因此可以通过引导加载程序将其加载到该内存区域中,并使用函数指针取消引用跳转到该区域。这是我正在使用的加载程序脚本: 这是我用于最终链接的命令行: (为简洁起见,省略了其余构建系统的详细信息,我认为这没有任何意义) 所以,我假设当我查看生成的controlix.o二进制文件时,应该看到位于0x200000的main()符号,对吗?错误: 我在做什么错了? 答案 0 :(得分:2) 我应该看到main()符号位于0x200000,对吧? 不。想象一下在调用main之前必须完成多少事情。在许多系统上,.bss置零和.data初始化以及许多我现在不记得的东西,必须初始化库,将其构造函数和析构函数称为(C ++)。 如果要先调用您的函数,请将其放在单独的段中并修改链接描述文件ENTRY(main)
SECTIONS
{
. = 0x0000000000200000;
.text : {
*(.text)
. = ALIGN(8);
}
.data : {
*(.data)
*(.rodata)
. = ALIGN(8);
}
__bss_start = .;
.bss : {
bss = .; _bss = .; __bss = .;
*(.bss);
}
end = .; _end = .; __end = .;
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
}
...
CC = g++
CFLAGS = -g -mcmodel=large -fPIC -T src/controlix.ld -Wl,--no-relax -static -nostdlib -static-libgcc
...
$(CC) $(CFLAGS) $(shell find bin/ -name "*.o") -o $(TARGET_OBJ)
$ nm bin/controlix.o |grep main
000000000021d0c6 t _GLOBAL__sub_D_main.cpp
000000000021d087 t _GLOBAL__sub_I_main.cpp
000000000021cef1 T main
0000000000256e11 t _ZL8eiremainPtS_P7LDPARMS
1 个答案:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
relativeLayout = findViewById(R.id.profile_layout);
backbutton = findViewById(R.id.backbutton);
backbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
settingsbtn = findViewById(R.id.settingsbtn);
settingsbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent settings_intent = new Intent(Profile.this, Settings.class);
startActivity(settings_intent);
}
});
artist_profile_p = findViewById(R.id.artist_profile_p);
makeup_artist_name = findViewById(R.id.makeup_artist_name);
mua_ratings = findViewById(R.id.mua_ratings);
final TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Images"));
tabLayout.addTab(tabLayout.newTab().setText("History"));
tabLayout.addTab(tabLayout.newTab().setText("Ratings"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabTextColors(Color.parseColor("#72716f"), Color.parseColor("#6a25af"));
final ViewPager viewPager = findViewById(R.id.pager);
PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
infoRef = FirebaseDatabase.getInstance().getReference().child("MakeUpArtists_Info").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
infoRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
final String image = dataSnapshot.child("image").getValue().toString();
String name = dataSnapshot.child("username").getValue().toString();
String rates = dataSnapshot.child("rates").getValue().toString();
makeup_artist_name.setText(name);
if (image.equals("default")) {
Picasso.with(Profile.this).load(R.drawable.no_image_two).placeholder(R.drawable.no_image_two).into(artist_profile_p);
} else {
Picasso.with(Profile.this).load(image).placeholder(R.drawable.no_image_two).into(artist_profile_p);
}
if (rates.equals("")) {
mua_ratings.setText("0.0");
} else {
mua_ratings.setText(rates);
}
artist_profile_p.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent image_intent = new Intent(Profile.this, ProfileM.class);
image_intent.putExtra("image", image);
Pair[] pairs = new Pair[1];
pairs[0] = new Pair<View, String>(artist_profile_p, "ImageTransition");
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(Profile.this, pairs);
startActivity(image_intent, options.toBundle());
}
});
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
/*if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, MY_PERMISSION_REQUEST_CODE);
}*/
change_dp = findViewById(R.id.change_dp);
change_dp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openStorage();
}
});
}
public void openStorage(){
Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(galleryIntent, "SELECT IMAGE"), GALLERY_PICK);
}
/*@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d("Access granted", "true");
}
}
}*/
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_PICK && resultCode == Activity.RESULT_OK) {
Uri imageUri = data.getData();
CropImage.activity(imageUri)
.setAspectRatio(1, 1)
.setMinCropWindowSize(500, 500)
.start(this);
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == Activity.RESULT_OK) {
mProgressDialog = new ProgressDialog(this, ProgressDialog.THEME_DEVICE_DEFAULT_DARK);
mProgressDialog.setTitle("Updating...");
mProgressDialog.setMessage("Please wait");
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
Uri resultUri = result.getUri();
File thumb_filePath = new File(resultUri.getPath());
final String current_user_id = FirebaseAuth.getInstance().getCurrentUser().getUid();
Random rand = new Random();
int n = rand.nextInt(50) + 1;
Bitmap thumb_bitmap = null;
try {
thumb_bitmap = new Compressor(this)
.setMaxWidth(500)
.setMaxHeight(500)
.setQuality(100)
.compressToBitmap(thumb_filePath);
} catch (IOException e) {
e.printStackTrace();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
thumb_bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
final byte[] thumb_byte = baos.toByteArray();
mImageStorage = FirebaseStorage.getInstance().getReference();
final StorageReference filepath = mImageStorage.child("MakeUpArtists").child("profile_images").child(current_user_id).child(n + ".jpg");
filepath.putBytes(thumb_byte).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> thumb_task) {
filepath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
final String download_url = uri.toString();
DatabaseReference ppRef = FirebaseDatabase.getInstance().getReference().child("MakeUpArtists_Info").child(current_user_id);
HashMap<String, Object> dpMap = new HashMap<>();
dpMap.put("image", download_url);
dpMap.put("thumb_image", download_url);
ppRef.updateChildren(dpMap).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
mProgressDialog.dismiss();
Snackbar.make(relativeLayout, "Successfully uploaded profile", Snackbar.LENGTH_LONG).show();
} else {
mProgressDialog.hide();
Snackbar.make(relativeLayout, "Error uploading profile picture", Snackbar.LENGTH_LONG).show();
}
}
});
}
});
}
});
} else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
Exception error = result.getError();
}
}
}
是main
程序的入口点,但(在几乎所有已知实现中)不是可执行文件的入口点。C
.text : {
*(.beforetext)
. = ALIGN(8);
__text_start = .;
*(.text)
. = ALIGN(8);
}